Microsoft SQL Server中存在一个表,其中包含记录ID,开始日期,结束日期和数量。
这个想法是,对于每条记录,数量/总天数范围=每日数量。
鉴于存在包含所有可能日期的表,如何在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 |
我可以获得的日期分组然后获得当天数量的总和,但由于用户提供的过滤器可能会排除某些记录,因此最终结果集无法汇总。
修改的
澄清一下,这只是一个例子。过滤器是无关紧要的,因为我可以加入到一边以提取与结果中的记录ID相关的详细信息。
真实数据包含每周增加的N条记录,日期永远不会相同。可能有2000条记录具有不同的开始和结束日期......这就是我想要生成视图的内容。我可以直接加入数据来完成我需要的其余部分
我还应该提到这是过去,现在和未来的数据。我很想摆脱一个临时的日期表。我使用递归查询来获取50年内存在的所有日期,但这超出了视图的MAXRECURSION限制,我无法使用。
答案 0 :(得分: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]
注意:下面的演示CTE使用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
答案 1 :(得分: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]