我有一張表,其中包含有關年銷售額的信息,其中日期是一年中的最後一個日期。因此,該模式是這樣的:非規範化年度表
endOfYearDate | metric1 | ... | metricN
我想非規範化此表有一行一年的每一天,該行從原來的行當年來的數據。所以度量將全部重複,但date
將會不同。
dailyDate | metric1 | ... | metricN
是否有SQL查詢可以輕鬆完成此操作?
我有一張表,其中包含有關年銷售額的信息,其中日期是一年中的最後一個日期。因此,該模式是這樣的:非規範化年度表
endOfYearDate | metric1 | ... | metricN
我想非規範化此表有一行一年的每一天,該行從原來的行當年來的數據。所以度量將全部重複,但date
將會不同。
dailyDate | metric1 | ... | metricN
是否有SQL查詢可以輕鬆完成此操作?
Declare @YourTable table (endOfYearDate date,metric1 int,metric2 int)
Insert Into @YourTable values
('2014-12-31',10,25),
('2015-12-31',35,50),
('2016-12-31',200,250)
;with cteMinMax As (
Select MinDate=DateAdd(YY,-1,min(endOfYearDate))
,MaxDate=DateAdd(YY, 1,max(endOfYearDate))
,Days =DateDiff(DD,DateAdd(YY,-1,min(endOfYearDate)),DateAdd(YY, 1,max(endOfYearDate)))
From @YourTable
)
,cte0(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N))
,cteD(D) As (Select Top (Select Days from cteMinMax) cast(DateAdd(DD,Row_Number() over (Order By (Select NULL)),(Select MinDate from cteMinMax)) as date) From cte0 N1, cte0 N2, cte0 N3, cte0 N4, cte0 N5, cte0 N6)
Select Date=D
,B.*
From cteD A
Join @YourTable B on Year(endOfYearDate)=Year(D)
Order By D
返回
使用帳簿表,與行1和N可以然後使用DATEPART(DAYOFYEAR,endOfYearDate)加入關於之間的每個整數的表。請注意,演繹表實際上只需要366個閏年值。使用這種方法實際上也適用於閏年。
Declare @YourTable table (endOfYearDate date,metric1 int,metric2 int)
Insert Into @YourTable values
('2014-12-31',10,25),
('2015-12-31',35,50),
('2016-12-31',200,250)
;WITH cte AS (Select 1 as N From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N))
,cteTally AS (
SELECT Number = ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM
cte n
CROSS JOIN cte n2
CROSS JOIN cte n3
)
SELECT
DATEADD(day,- t.Number + 1, yt.endOfYearDate) as Date
,yt.endOfYearDate
,yt.metric1
,yt.metric2
FROM
@YourTable yt
INNER JOIN cteTally t
ON DATEPART(dayofyear,yt.endOfYearDate) >= t.Number
ORDER BY
Date
@約翰基本上體現了我想寫我就回來了,但是通過使用DAYOFYEAR,而不是生成所有日期的前指理貨表是顯著更小,執行速度快了很多。
只要一個日期dimmension。我和許多其他人實際上實現了一個日期表來處理它,使得大量的連接等變得更加容易,如果你有一個你只需要一個內部連接來獲得你想要的結果。微軟SSAS將爲您生成一個,或者您可以構建一個腳本來構建自己的腳本。
這裏是做遞歸的一種方法。你會注意到我必須將遞歸的最大級別設置爲365(366 - 1)。
;WITH cteRecursive AS (
SELECT endOfYearDate as Date, DATEPART(dayofyear,endOfYearDate) as DOY, endOfYearDate, metric1, metric2
FROM
@YourTable
UNION ALL
SELECT
DATEADD(day,-1,Date)
,DOY - 1
,endOfYearDate
,metric1
,metric2
FROM
cteRecursive
WHERE
DOY - 1 > 0
)
SELECT Date, endOfYearDate, metric1, metric2
FROM
cteRecursive
ORDER BY
Date
OPTION (maxrecursion 365)
請問您能解釋一下嗎? – user1742188