如果我有一个像这样的桌子
begin date end date data 2013-01-01 2013-01-04 7 2013-01-05 2013-01-06 9
我如何才能像这样退货…
date data 2013-01-01 7 2013-01-02 7 2013-01-03 7 2013-01-04 7 2013-01-05 9 2013-01-06 9
我正在考虑做的一件事是让另一个具有全部日期的表,然后使用date>=begin date和将仅具有日期的表加入到上述表中,date<=end date但这似乎有点笨拙,因为除了重复的日期外,别无其他维护该表的必要性。
date>=begin date
date<=end date
在某些情况下,我没有数据范围,而只有一个as of日期,基本上看起来像我的第一个示例,但没有end date。该end date由下一行的“作为”日暗示(即结束日期应该是下一行的as of-1)。为此,我有一个“解决方案”,它使用row_number()函数获取下一个值,但我怀疑这种方法(这种方法具有大量嵌套的自我联接)会导致很长的查询时间。
as of
end date
使用一些样本数据…
create table data (begindate datetime, enddate datetime, data int); insert data select '20130101', '20130104', 7 union all select '20130105', '20130106', 9;
查询 :(注意:如果您已经有一个数字/理货表格,请使用它)
select dateadd(d,v.number,d.begindate) adate, data from data d join master..spt_values v on v.type='P' and v.number between 0 and datediff(d, begindate, enddate) order by adate;
结果 :
| COLUMN_0 | DATA | ----------------------------------------- | January, 01 2013 00:00:00+0000 | 7 | | January, 02 2013 00:00:00+0000 | 7 | | January, 03 2013 00:00:00+0000 | 7 | | January, 04 2013 00:00:00+0000 | 7 | | January, 05 2013 00:00:00+0000 | 9 | | January, 06 2013 00:00:00+0000 | 9 |
或者,您可以即时生成号码表(0-99),也可以根据需要生成任意数量的号码
;WITH Numbers(number) AS ( select top(100) row_number() over (order by (select 0))-1 from sys.columns a cross join sys.columns b cross join sys.columns c cross join sys.columns d ) select dateadd(d,v.number,d.begindate) adate, data from data d join Numbers v on v.number between 0 and datediff(d, begindate, enddate) order by adate;
SQL小提琴演示