我有2个日期,StartDate
和EndDate
:
Declare @StartDate date='2018/01/01', @Enddate date ='2018/12/31'
然后在mytable表中有一些带有date
和value
的数据:
----------------------------
ID date value
----------------------------
1 2018/02/14 4
2 2018/09/26 7
3 2017/09/20 2
数据可能在2018年之前开始,并且如果它在@startdate之前存在,则在值之前 否则得到0 我正在寻找一个看起来像这样的结果:
-----------------------------------
fromdate todate value
-----------------------------------
2018/01/01 2018/02/13 2
2018/02/14 2018/09/25 4
2018/09/26 2018/12/31 7
第一个fromdate
来自@StartDate
,最后一个todate
来自@Enddate
,并且应该生成其他数据。
我希望在SQL查询中得到它。我使用sql-server 2016
答案 0 :(得分:1)
with cte as
(
select 0 as row_num, @StartDate as start_date, 0 as val
UNION
select ROW_NUMBER() OVER(ORDER BY start_date) as row_num, * from input
)
select curr.start_date
, DATEADD(day,-1,ISNULL(nex.start_date,DATEADD(day,1,@Enddate))) as end_date
, curr.val
from cte curr
left join cte nex on curr.row_num = nex.row_num - 1;
您可以在此处找到模拟:https://rextester.com/EIAXW23839
答案 1 :(得分:1)
您可以使用CTE创建完整的日期范围,然后使用LEAD
创建ToDate
列:
DECLARE @FromDate date = '20180101',
@ToDate date = '20181231';
WITH VTE AS(
SELECT ID,
CONVERT(date,[date]) [date], --This is why using keywords for column names is a bad idea
[value]
FROM (VALUES(1,'20180214',4),
(2,'20180926',7),
(3,'20170314',4))V(ID,[date],[value])),
Dates AS(
SELECT [date]
FROM VTE V
WHERE V.[date] BETWEEN @FromDate and @ToDate
UNION ALL
SELECT [date]
FROM (VALUES(@FromDate))V([date]))
SELECT D.[date] AS FromDate,
LEAD(DATEADD(DAY, -1,D.[date]),1,@ToDate) OVER (ORDER BY D.[date]) AS ToDate,
ISNULL(V.[value],0) AS [value]
FROM Dates D
LEFT JOIN VTE V ON D.[date] = V.[date];