I want to display 12 months name from sql server. i though to accomplish insert month name into temp table and then fire select statement on that table. so i had to write 12 insert table to insert 12 months name. so i search google to find better solution and i got it.
here is the sql statement
WITH R(N) AS
(
SELECT 0
UNION ALL
SELECT N+1
FROM R
WHERE N < 12
)
SELECT LEFT(DATENAME(MONTH,DATEADD(MONTH,-N,GETDATE())),3) AS [month]
FROM R
the above script works perfectly but my problem is i just do not understand how it works. i never work with CTE.
so tell me what is the meaning of WITH R(N) AS
and see this sql
SELECT LEFT(DATENAME(MONTH,DATEADD(MONTH,-N,GETDATE())),3) AS [month] FROM R
when above sql execute how it is getting value for -N ??
because here i have not set anything for -N ??
so please anyone help me to understand how whole thing works. thaks
My Second Phase of Question
just have look a and tell me
;WITH months(MonthNumber) AS
(
SELECT 0
UNION ALL
SELECT MonthNumber+1
FROM months
WHERE MonthNumber < 12
)
onething is not clear to me that why only first time the below part execute
SELECT 0
UNION ALL
SELECT MonthNumber+1
FROM months
WHERE MonthNumber < 12
and from the 2nd time only this below part execute
SELECT MonthNumber+1
FROM months
WHERE MonthNumber < 12
whenever we write two sql statement using Union and execute then always it return data from two sql state but specially in this case from the 2nd time why only this below part execute
SELECT MonthNumber+1
FROM months
WHERE MonthNumber < 12
basically i not familiar with CTE with recursion technique and that is why things is not getting clear to me. if possible please discuss how CTE recursion works.
DECLARE @TotaDays SMALLINT
DECLARE @Month VARCHAR(15)
DECLARE @Year SMALLINT
DECLARE @date DATETIME
SET @Month = 'January'
SET @Year = 2015
SET @date = '01 ' + @Month + ' ' + CONVERT(VARCHAR(4),@Year)
SET @TotaDays = 0
SELECT @TotaDays = DATEDIFF(DAY, @date, DATEADD(MONTH, 1, @date))
;WITH months(MonthNumber) AS
(
SELECT 1
UNION ALL
SELECT MonthNumber+1
FROM months
WHERE MonthNumber < @TotaDays
)
select * from months;
9条答案
按热度按时间dffbzjpn1#
The
With R(N)
is a Common Table Expression . From MDSN:A common table expression (CTE) can be thought of as a temporary result set that is defined within the execution scope of a single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement. A CTE is similar to a derived table in that it is not stored as an object and lasts only for the duration of the query. Unlike a derived table, a CTE can be self-referencing and can be referenced multiple times in the same query.
The
R
is the name of the result set (or table) that you are generating. And theN
is themonth
number.This CTE in particular is a Recursive Common Table Expression . From MSDN:
A common table expression (CTE) provides the significant advantage of being able to reference itself, thereby creating a recursive CTE. A recursive CTE is one in which an initial CTE is repeatedly executed to return subsets of data until the complete result set is obtained.
When using CTE my suggestion would to be more descriptive with the names. So for your example you could use the following:
In my version the
months
is the name of the result set that you are producing and themonthnumber
is the value. This produces a list of the Month Numbers from 0-12 (See Demo).Result:
Then the
SELECT
statement immediately after is using the values of the CTE result set to get you the Month Names.Final query (See Demo):
vd2z7a6w2#
This query is to obtain all month names and month no's
j2datikz3#
Try This,
j2cgzkjk4#
R
defines the name of the CTE, and(N)
defines the name of the column(s) in the CTE - in this case there is only one column.You can see that you are selecting from R in the second part of the statement.
You are indeed setting the value of
(N)
when youselect 0
, i.e. the first and only column in the anchor portion of the CTE definition and later on when specifyingselect N+1
in the recursive part of the CTE definition.thtygnil5#
Try changing the second part of the code, that way you will see what is generated in the recursive part:
You will obtain this result:
By the way, i think it would be better to do
SELECT 1
instead ofSELECT 0
, so that you generate exactly 12 numbers and therefore you won't end up having an extra monthwmtdaxz36#
This query obtain information per period of time and get the list:
72qzrwbm7#
I modified to code shared earlier to give 12-month names with their respective month numbers in required sequence. Also, removed the dependency on the current date by adding 1st Jan 1900 as the fixed date.
u1ehiz5o8#
this gives the answer as
vyu0f0g19#
I think you are expecting this by seeing this you can understand Thank you.
with months(mnum) as (select 0 union all select mnum+1 from months where mnum <11) select left(datename(month,dateadd(month,mnum,getdate())),3) as mn from months
David raja