在SQL Server 2008中连续合并连续记录

发布于 2025-02-08 19:16:59 字数 2260 浏览 2 评论 0原文

假设我有这样的数据,时间段基本上是相隔30分钟的时间。 请注意,在15:30至16:30之间,2021-12-24中存在差距。

CALENDER_DATETIMESLOTTIMESLOT_END
2021-12-2414:00:0014:30:00
2021-12-2414:30:0015:00 15:00
2021-12-2415:00 15:0015:30:00
2021- 12-2416:30:0017:00:00
2021-12-2417:00:0017:30:00
2021-12-2417:30:0018:00:00
2021-12-3009: 00:0009:30:00
2021-12-3009:30:0010:00:00

我想合并行时lipslot_end = Next Row的时光段,并且在同一天,因此数据看起来像这样。

CALENDER_DATETIMESLOTTIMESLOT_END
2021-12-2414:00:0015:30:00
2021-12-2416:30:0018:00:00
2021-12-309:0010:00

我有尝试使用自连接的行编号,

WITH cte AS
(
    SELECT       
                calender_date 
                ,timeslot
                ,timeslot_end
                ,ROW_NUMBER()OVER(ORDER BY [timeslot])rn
    
    FROM @tmp_leave tl
)

SELECT  
        MIN(a.timeslot) OVER(PARTITION BY a.calender_date, DATEDIFF(minute,a.timeslot_end, 
            ISNULL(b.timeslot, a.timeslot_end))) AS 'StartTime',
        MAX(a.timeslot_end ) OVER(PARTITION BY a.calender_date, 
            DATEDIFF(minute,a.timeslot_end, ISNULL(b.timeslot, a.timeslot_end))) AS 'EndTime'
        
FROM cte a 
LEFT JOIN cte b
       ON a.rn + 1 = b.rn AND a.timeslot_end = b.timeslot
ORDER BY calender_date

但是结果不太正确,它忽略了2021-12-24中的差距,并在下面返回。

calender_datetimeslottimeslot_end
2021-12-2414:00:0018:00:00
2021-12-309:00:0010:00:00

我一直在搜索并尝试解决一段时间,请帮助,请帮助,任何帮助都非常感谢!!

Say I have data like this, timeslots is basically time with 30 mins apart.
Note there is a gap in 2021-12-24 between 15:30 and 16:30.

calender_datetimeslottimeslot_end
2021-12-2414:00:0014:30:00
2021-12-2414:30:0015:00:00
2021-12-2415:00:0015:30:00
2021-12-2416:30:0017:00:00
2021-12-2417:00:0017:30:00
2021-12-2417:30:0018:00:00
2021-12-3009:00:0009:30:00
2021-12-3009:30:0010:00:00

I want to merge rows where timeslot_end = next row's timeslot and in the same day, so data would look like this.

calender_datetimeslottimeslot_end
2021-12-2414:00:0015:30:00
2021-12-2416:30:0018:00:00
2021-12-309:00:0010:00:00

I have try row numbering with self join,

WITH cte AS
(
    SELECT       
                calender_date 
                ,timeslot
                ,timeslot_end
                ,ROW_NUMBER()OVER(ORDER BY [timeslot])rn
    
    FROM @tmp_leave tl
)

SELECT  
        MIN(a.timeslot) OVER(PARTITION BY a.calender_date, DATEDIFF(minute,a.timeslot_end, 
            ISNULL(b.timeslot, a.timeslot_end))) AS 'StartTime',
        MAX(a.timeslot_end ) OVER(PARTITION BY a.calender_date, 
            DATEDIFF(minute,a.timeslot_end, ISNULL(b.timeslot, a.timeslot_end))) AS 'EndTime'
        
FROM cte a 
LEFT JOIN cte b
       ON a.rn + 1 = b.rn AND a.timeslot_end = b.timeslot
ORDER BY calender_date

But the result isn't quite right, it ignored the gap in 2021-12-24 and return below.

calender_datetimeslottimeslot_end
2021-12-2414:00:0018:00:00
2021-12-309:00:0010:00:00

I have been searching and trying to solve it for a while now, please help, any help is very very appreciated!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冰雪之触 2025-02-15 19:16:59

这是一个差距和岛屿问题。我们可以通过为每个连续日期/时间创建伪群来解决这个问题。

WITH cte AS (
    SELECT *, LAG(timeslot_end) OVER
                  (ORDER BY calendar_date, timeslot) timeslot_end_lag
    FROM yourTable
),
cte2 AS (
    SELECT *, COUNT(CASE WHEN timeslot_end_lag <> timeslot THEN 1 END)
                  OVER (ORDER BY calendar_date, timeslot) AS grp
    FROM cte
)

SELECT calendar_date,
       MIN(timeslot) AS timeslot,
       MAX(timeslot_end) AS timeslot_end
FROM cte2
GROUP BY calendar_date, grp
ORDER BY calendar_date;

amp

demo

This is a gaps and islands problem. We can approach this by creating pseudo groups for each island of continuous dates/times.

WITH cte AS (
    SELECT *, LAG(timeslot_end) OVER
                  (ORDER BY calendar_date, timeslot) timeslot_end_lag
    FROM yourTable
),
cte2 AS (
    SELECT *, COUNT(CASE WHEN timeslot_end_lag <> timeslot THEN 1 END)
                  OVER (ORDER BY calendar_date, timeslot) AS grp
    FROM cte
)

SELECT calendar_date,
       MIN(timeslot) AS timeslot,
       MAX(timeslot_end) AS timeslot_end
FROM cte2
GROUP BY calendar_date, grp
ORDER BY calendar_date;

Demo

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文