我只是创建一个计划项目并需要帮助..
我有一个日程安排数据
ID Programme Start End Division
----------------------------------------------------------
M001 Math 1/1/2017 20/01/2017 Math
M002 Aljabar 2/2/2017 20/02/2017 Math
E001 Conversation 3/1/2017 25/01/2017 English
E002 Vocabs 3/1/2017 20/02/2017 English
我需要让它看起来像这样:
ID Date
------------------
M001 1/1/2017
M001 2/1/2017
M001 3/1/2017
so on until 20/1/2017
M002 2/2/2017
M002 3/2/2017
so on until 20/02/2017
E001 3/1/2017
E001 4/1/2017
so on until 25/01/2017
E002 3/1/2017
E002 4/1/2017
so on until 20/02/2017
由于
答案 0 :(得分:3)
执行此操作的一种方法是使用递归CTE:
with cte as (
select id, start as dte, end
from t
union all
select id, dateadd(day, 1, dte), end
from t
where dte < end
)
select id, dte
from cte
order by id, dte;
如果您有超过100天的时间,则需要使用MAXRECURSION
选项。
注意:上面保留了问题中指定的列,假设这些列不是真实姓名。显然,end
是保留字(并且start
可能是将来的一个),因此如果它们是实际的列名,则应对其进行转义。
答案 1 :(得分:1)
您需要一个日历表来执行此操作。我宁愿在我的数据库中创建一个物理日历表,并在这种情况下使用它。以下是使用计数表方法动态生成日期的一种方法
DECLARE @minDate DATETIME
SELECT @minDate = Min([Start])
FROM Yourtable
;WITH lv0 AS (SELECT 0 g UNION ALL SELECT 0)
,lv1 AS (SELECT 0 g FROM lv0 a CROSS JOIN lv0 b) -- 4
,lv2 AS (SELECT 0 g FROM lv1 a CROSS JOIN lv1 b) -- 16
,lv3 AS (SELECT 0 g FROM lv2 a CROSS JOIN lv2 b) -- 256
,lv4 AS (SELECT 0 g FROM lv3 a CROSS JOIN lv3 b) -- 65,536
,Tally (n) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM lv3)
SELECT ID,
Dateadd(DD, n - 1, @minDate)
FROM Tally t
JOIN Yourtable a
ON Dateadd(DD, t.n - 1, @minDate) BETWEEN [Start] AND [End]
ORDER BY ID,n;
如果您想了解有关计数表的更多信息,请查看此链接Tally Tables in T-SQL