我希望将数据行转换为sql中的日期范围。 以下是样本数据
#Slno MonthDate System#
1 7/1/2017 SystemA
1 8/1/2017 SystemA
1 9/1/2017 SystemB
1 10/1/2017 SystemB
1 11/1/2017 SystemB
1 12/1/2017 SystemA
1 1/1/2018 SystemA
1 2/1/2018 SystemA
1 3/1/2018 SystemB
2 12/1/2017 SystemA
2 1/1/2018 SystemB
3 2/1/2018 SystemA
4 3/1/2018 SystemB
和期望的输出是
#Slno StartDate EndDate System#
1 7/1/2017 8/1/2017 SystemA
1 9/1/2017 11/1/2017 SystemB
1 12/1/2017 3/1/2018 SystemA
2 12/1/2017 12/1/2017 SystemA
2 1/1/2018 1/1/2018 SystemB
3 2/1/2018 2/1/2018 SystemA
4 3/1/2018 3/1/2018 SystemB
答案 0 :(得分:3)
您可以使用"行号的差异"方法:
select slno, system, min(date), max(date)
from (select t.*,
row_number() over (partition by slno order by date) as seqnum_s,
row_number() over (partition by slno, system order by date) as seqnum_ss
from t
) t
group by slno, system, (seqnum_s - seqnum_ss);
这个逻辑有点棘手。根据我的经验,您可以运行子查询并盯着结果。您应该能够看到行号的差异如何定义相邻行中由相等值定义的组。
答案 1 :(得分:0)
这是使用窗口函数的另一种方法
;WITH cte
AS (SELECT *,
Grp = Sum(CASE WHEN System = prev_System THEN 0 ELSE 1 END)
OVER(partition BY Slno ORDER BY MonthDate)
FROM (SELECT *,
prev_System = Lag(System)OVER(partition BY Slno ORDER BY MonthDate)
FROM Yourtable) a)
SELECT Slno, System, Min(MonthDate), Max(MonthDate)
FROM cte
GROUP BY Slno, System, Grp
Lag(System)OVER(partition BY Slno ORDER BY MonthDate)
可帮助您识别每个月份的先前系统
Sum(CASE WHEN System = prev_System THEN 0 ELSE 1 END) OVER(partition BY Slno ORDER BY MonthDate)
可帮助您在上一个系统和当前系统相同时创建组
注意:这可以从Sql Server 2012