开发者

SQL Query for Date Range, multiple start/end times

A table exists in Microsoft SQL Server with record ID, Start Date, End Date and Quantity.

The idea is that for each record, the quantity/total days in range = daily quantity.

Given that a table containing all possible dates exists, how can I generate a result set in SQL Server to look like the following example?

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 nee开发者_Go百科d 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 | 

Grouping on dates I could get then get the sum of quantity on that day however the final result set can't be aggregate due to user provided filters that may exclude some of these records down the road.

EDIT

To clarify, this is just a sample. The filters are irrelevant as I can join to the side to pull in details related to the record ID in the results.

The real data contains N records which increases weekly, the dates are never the same. There could be 2000 records with different start and end dates... That is what I want to generate a view for. I can right join onto the data to do the rest of what I need

I should also mention this is for past, present and future data. I would love to get rid of a temporary table of dates. I was using a recursive query to get all dates that exist within a 50 year span but this exceeds MAXRECURSION limits for a view, that I cannot use.


Answer

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]

NB: The below demo CTEs use the date datatype which is SQL Server 2008 the general approach should work for SQL2005 as well though.

Test Case

/*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]

Results

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


I think you can try this.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜