2010-07-20 131 views
0

Microsoft SQL Server中存在一個表,其中包含記錄標識,開始日期,結束日期和數量。針對日期範圍的SQL查詢,多個開始/結束時間

這個想法是,對於每個記錄,範圍內的數量/總天數=每日數量。

鑑於包含所有可能日期的表存在,我如何在SQL Server中生成結果集,使其看起來像下面的示例一樣?

EX:

RecordID | Start Date | End Date | Quantity 
1  | 1/1/2010 | 1/5/2010 | 30000 
2  | 1/3/2010 | 1/9/2010 | 20000 
3  | 1/1/2010 | 1/7/2010 | 10000 

Results as 
1  | 1/1/2010 | QTY (I can do the math easy, just need the dates view) 
1  | 1/2/2010 | 
1  | 1/3/2010 | 
1  | 1/4/2010 | 
1  | 1/3/2010 | 
2  | 1/4/2010 | 
2  | 1/5/2010 | 
2  | 1/6/2010 | 
2  | 1/7/2010 | 
2  | 1/8/2010 | 
2  | 1/9/2010 | 
3  | 1/1/2010 | 
3  | 1/2/2010 | 
3  | 1/3/2010 | 
3  | 1/4/2010 | 
3  | 1/5/2010 | 
3  | 1/6/2010 | 
3  | 1/7/2010 | 

分組的日期,我能得到那麼得到的那一天量的總和不過最終的結果集不能總因爲這可能會排除某些記錄用戶提供過濾器在路上。

EDIT

爲了澄清,這僅僅是一個示例。過濾器是無關緊要的,因爲我可以加入到側面來獲取結果中與記錄ID相關的詳細信息。

真實數據包含每週增加的N個記錄,日期從不相同。可能有2000條記錄具有不同的開始日期和結束日期......這是我想爲其生成視圖。我可以正確加入數據,以完成我需要的其餘部分。

我還應該提到這是針對過去,現在和將來的數據。我很想擺脫一個臨時的日期表。我使用遞歸查詢來獲取50年內存在的所有日期,但這超出了MAXRECURSION對於視圖的限制,我無法使用。

+0

我不知道我的理解對用戶提供的濾光器的信息。你能提供更多細節嗎? – bobs 2010-07-20 21:50:39

+0

這些過濾器真的無關緊要。我會把這個列表加入到主列表中,其中包含關於數量等的信息,並可以使用這些事實來推導出所有的值。 – Mohgeroth 2010-07-20 23:09:38

回答

3

回答

select RecordId,d.[Date], Qty/ COUNT(*) OVER (PARTITION BY RecordId) AS Qty 
from EX join Dates d on d.Date between [Start Date] and [End Date] 
ORDER BY RecordId,[Date] 

注:以下演示熱膨脹係數使用date數據類型是SQL Server 2008中的一般方法應該爲SQL2005工作,但也。

測試用例

/*CTEs for testing purposes only*/ 

WITH EX AS 
(
    SELECT 1 AS RecordId, 
    cast('1/1/2010' as date) as [Start Date], 
    cast('1/5/2010' as date) as [End Date], 
    30000 AS Qty 
union all 
    SELECT 2 AS RecordId, 
    cast('1/3/2010' as date) as [Start Date], 
    cast('1/9/2010' as date) as [End Date], 
    20000 AS Qty 
),Dates AS /*Dates Table now adjusted to do greater range*/ 
(

SELECT DATEADD(day,s1.number + 2048*s2.number,'1990-01-01') AS [Date] 
FROM master.dbo.spt_values s1 CROSS JOIN master.dbo.spt_values s2 
where s1.type='P' AND s2.type='P' and s2.number <= 8 
order by [Date] 
) 


select RecordId,d.[Date], Qty/ COUNT(*) OVER (PARTITION BY RecordId) AS Qty 
from EX join Dates d on d.Date between [Start Date] and [End Date] 
ORDER BY RecordId,[Date] 

結果

RecordId Date  Qty 
----------- ---------- ----------- 
1   2010-01-01 6000 
1   2010-01-02 6000 
1   2010-01-03 6000 
1   2010-01-04 6000 
1   2010-01-05 6000 
2   2010-01-03 2857 
2   2010-01-04 2857 
2   2010-01-05 2857 
2   2010-01-06 2857 
2   2010-01-07 2857 
2   2010-01-08 2857 
2   2010-01-09 2857 
+0

我沒有提到這是過去,現在和將來的數據。我喜歡這樣的想法,即我不必從臨時表中獲取日期,但不幸的是,這可能會向前推進兩年,對這些結果使用此查詢不會爲未來的數據產生任何結果。我很想擺脫這個臨時日期表,儘管... – Mohgeroth 2010-07-20 23:17:35

+0

@Mohgeroth - 具有日期索引的專用日期表將是最有效的解決方案。你應該能夠輕鬆地調整我的查詢來查看,而不是我的演示日期表。 – 2010-07-20 23:55:46

+0

你是什麼意思「未來日期」?他的查詢適用於長達22年以上的跨度,無論他們是過去還是未來。如果您的意思是您希望在數量爲0的數量列表中看到將來的日期,例如「2011-01-01 0」,那麼您必須包含一個指定開始和結束總日期範圍的參數。 – ErikE 2010-07-20 23:59:36

1

我想你可以試試這個。

SELECT [Quantities].[RecordID], [Dates].[Date], SUM([Quantity]) 
FROM [Dates] 
JOIN [Quantities] on [Dates].[Date] between [Quantities].[Start Date] and [End Date] 
GROUP BY [Quantities].[RecordID], [Dates].[Date] 
ORDER BY [Quantities].[RecordID], [Dates].[Date] 
+0

美麗。我沒想過在我的加入手術中使用。我仍然有這個我希望消除的日期表,但如果不能這樣做,這是一個乾淨的解決方案 – Mohgeroth 2010-07-20 23:08:41

相關問題