完成这项工作的诀窍是有一个表格,其中包含可能范围内的所有日期的列表。
在下面的查询中,我使用我们集合MIN(Start) 中的最小日期来伪造它。
然后,我根据 sys.all_columns 视图中的列数生成从 1 到 N 的数字序列。这可能就足够了,它可能不是,但基于数据的缺乏,它现在可以工作。如果您需要生成更多日期,请针对自身交叉应用 sys.all_coumns 表。
然后我使用生成的数字通过dateadd 构建日期列表
然后,我使用我的 ALLDATES 派生表并对原始表执行 INNER JOIN,将为 ALLDATES 生成的日期固定在 Start 和 End 列之间(包括端点)。
CREATE TABLE dbo.so_36392684
(
WeekNo int NOT NULL
, Start datetime NOT NULL
, [End] datetime NOT NULL
, SpecialEvents varchar(20) NULL
);
INSERT INTO
dbo.so_36392684
(WeekNo, Start, [End], SpecialEvents)
VALUES
(
1
, '1989-09-14'
, '1989-09-20'
, NULL
);
SELECT
S.WeekNo
, S.Start
, S.[End]
, S.SpecialEvents
, ALLDATES.ConsecutiveDays
FROM
(
SELECT
DATEADD(DAY, D.rn, S.Start) AS ConsecutiveDays
FROM
(
-- Find the first date in our table
SELECT
MIN(S.Start) AS Start
FROM
dbo.so_36392684 AS S
) AS S
CROSS APPLY
(
-- Generate a (hopefully) sufficiently large enough set of dates
SELECT
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS rn
FROM
sys.all_columns AS AC
) D
) AS ALLDATES
INNER JOIN
dbo.so_36392684 AS S
ON ALLDATES.ConsecutiveDays >= S.Start
AND ALLDATES.ConsecutiveDays <= S.[End];
结果应该是这样的
WeekNo Start End SpecialEvents ConsecutiveDays
1 1989-09-14 1989-09-20 NULL 1989-09-14
1 1989-09-14 1989-09-20 NULL 1989-09-15
1 1989-09-14 1989-09-20 NULL 1989-09-16
1 1989-09-14 1989-09-20 NULL 1989-09-17
1 1989-09-14 1989-09-20 NULL 1989-09-18
1 1989-09-14 1989-09-20 NULL 1989-09-19
1 1989-09-14 1989-09-20 NULL 1989-09-20