比方说,我有一个下表,如下所示(具有多个日期范围的多个项目):
Project | Start_Date | End_Date
ABC123 10/19/2018 12/31/2018
是否可以将其查询到如下所示的结果集中?
Project | Start_Date | End_Date
ABC123 10/19/18 10/31/18
ABC123 11/01/18 11/30/18
ABC123 12/01/18 12/31/18
答案 0 :(得分:1)
这可能需要更多的优化,但要像现在一样提供预期的输出
WITH TEMP1 (PROJECT,START_DATE , END_DATE, DT) AS
(
SELECT PROJECT,START_DATE
,END_DATE
,START_DATE DT
FROM MYTABLE
UNION ALL
SELECT PROJECT
,START_DATE
,END_DATE
,DATEADD(DAY, 1, DT) DT
FROM TEMP1
WHERE DT < END_DATE
)
,TEMP2 AS(
SELECT PROJECT
,DATEADD(MONTH, DATEDIFF(MONTH, 0, DT), 0) STARTDATE
,EOMONTH(DT ) ENDDATE
FROM TEMP1
GROUP BY PROJECT
,DATEADD(MONTH, DATEDIFF(MONTH, 0, DT), 0)
,EOMONTH(DT )
)
SELECT B.PROJECT
,CASE WHEN B.STARTDATE < A.START_DATE THEN A.START_DATE
ELSE B.STARTDATE END AS STARTDATEFINAL
,CASE WHEN B.ENDDATE > A.END_DATE THEN A.END_DATE
ELSE B.ENDDATE END AS ENDDATEFINAL
FROM MYTABLE A, TEMP2 B
WHERE A.PROJECT = B.PROJECT
答案 1 :(得分:0)
您可以使用递归CTE:
with cte as (
select project, start_date, eomonth(start_date) as end_date, end_date as final_date
from t
union all
select project, dateadd(day, 1, end_date), eomonth(dateadd(day, 1, end_date)), final_date
from cte
where end_date < final_date
)
select project_start_date, end_date
from cte;
请注意,您的问题在某些方面有点模棱两可。值得注意的是,这假定:
这些与您的样本数据一致。使用条件逻辑修改查询以处理这些问题非常容易。
编辑:
对于注释中的条件:
with cte as (
select project, start_date,
(case when end_date < eomonth(start_date) then end_date
else eomonth(start_date)
end) as end_date,
end_date an final_date
from t
union all
select project, start_date,
(case when end_date < eomonth(start_date) then end_date
else eomonth(start_date)
end) as end_date,
end_date as final_date
from t
union all
select project, dateadd(day, 1, end_date),
(case when final_date < eomonth(dateadd(day, 1, end_date))
then final_date
else eomonth(dateadd(day, 1, end_date))
end), final_date
from cte
where end_date < final_date
)
select project_start_date, end_date
from cte;
这里是db<>fiddle。