使用CTE遞歸的方式實現時間維度表

關於CTE遞歸的語法,本人也是剛剛接觸到,在介紹這個生成時間維度表之前,我先簡單介紹一下CTE遞歸的語法吧!以方便初學者更容易理解(老司機可以無視)。
廢話不多說,直接上SQL:

with A as
    (
        select 1 NUM
        union all
        select NUM+1 from A
        where NUM<20
	)
    select * from A 
    Option(MAXRECURSION 100)  --設置最大的遞歸次數

這應該算是最簡單的例子了吧,意思就是從1數到20,執行結果如下:


看到這裏相信你對CTE遞歸的基本語法應該有所熟悉了哈~
下面再來一個只輸出日期的SQL:

with CTE as
    (
        select cast('2000-1-1' as date) dt
        union all
        select dateadd(day,1,dt) from CTE
        where dt<getdate()
    )
    select * from CTE 
    Option(MAXRECURSION 20000)  
執行結果:

這段SQL將日期從2000-01-01 到當前日期,一天不差的輸出出來了。

最後,在這基礎之上,開始我們今天的正題:生成時間維度表吧!
with CTE as
    (
        select cast('2000-1-1' as date) DateID
			  ,year( cast('2000-1-1' as date)) [Year]
			  ,month(cast('2000-1-1' as date))[Month]
			  ,day(cast('2000-1-1' as date))[Day]
			  ,CASE DATEPART(QUARTER, cast('2000-1-1' as date))
				   WHEN 1 THEN N'第一季度'
				   WHEN 2 THEN N'第二季度'
				   WHEN 3 THEN N'第三季度'
				   ELSE N'第四季度' END AS [Quarter]			       
			  ,CASE DATEPART(W, cast('2000-1-1' as date))
				   WHEN 1 THEN N'星期一'
				   WHEN 2 THEN N'星期二'
				   WHEN 3 THEN N'星期三'
				   WHEN 4 THEN N'星期四'
				   WHEN 5 THEN N'星期五'
				   WHEN 6 THEN N'星期六'
				   ELSE N'星期日' END AS [WeekDay]	
			  ,N'第'+CAST( DATEPART(WEEK, cast('2000-1-1' as date)) AS VARCHAR(2))+'周' AS [Week]		   
        union all
        select dateadd(day,1,DateID)
			  ,year(dateadd(day,1,DateID))
			  ,month(dateadd(day,1,DateID))
			  ,day(dateadd(day,1,DateID))
			  ,CASE DATEPART(QUARTER,dateadd(day,1,DateID))
				   WHEN 1 THEN N'第一季度'
				   WHEN 2 THEN N'第二季度'
				   WHEN 3 THEN N'第三季度'
				   ELSE N'第四季度' END AS [Quarter]	
			  ,CASE DATEPART(W, dateadd(day,1,DateID))
				   WHEN 1 THEN N'星期一'
				   WHEN 2 THEN N'星期二'
				   WHEN 3 THEN N'星期三'
				   WHEN 4 THEN N'星期四'
				   WHEN 5 THEN N'星期五'
				   WHEN 6 THEN N'星期六'
				   ELSE N'星期日' END AS [Week]	
			  ,N'第'+CAST( DATEPART(WEEK, dateadd(day,1,DateID)) AS VARCHAR(2))+'周' AS [Week]	
		from CTE
        where DateID<cast(getdate() as date)
    )
    select * from CTE 
	Option(MAXRECURSION 7000) --設置最大的遞歸次數,如果沒有這一段,默認最大遞歸100次

最後展示一下最終結果:


如果你覺得這些欄位不夠,還需要其他欄位的,可以根據需要結合時間函數在這基礎之上追加列。

有不明白的地方可以給我留言,或者加我VX:838599867,有問題或者新技術可以一起研究哈^_^



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章