将每个id的多个时间值分组为一个时间段,并使用sql显示每个时间段

7ivaypg9  于 2021-08-13  发布在  Java
关注(0)|答案(1)|浏览(519)

有没有一种方法可以解决sql查询中的以下问题?假设microsoft sql server数据库中有下表:

date_time                         | tool_id
----------------------------------|-----------------
2020-02-18 12:00:00.0100000       | 4
2020-02-18 12:00:00.0200000       | 5
2020-02-18 12:00:00.0300000       | 5
2020-02-18 12:00:00.0400000       | 5
2020-02-18 12:00:00.0500000       | 7
2020-02-18 12:00:00.0600000       | 7
2020-02-18 12:00:00.0700000       | 7
2020-02-18 12:00:00.0800000       | 4
2020-02-18 12:00:00.0900000       | 4
2020-02-18 12:00:00.1000000       | 4

date_time是按时间顺序排列的datetime,tool_id是一个int,对应于在特定时间戳在机器中使用的特定工具。刀具在机器中使用了一定的时间段(例如,刀具7从'2020-02-18 12:00:00.0500000'到'2020-02-18 12:00:00.0700000'使用)。我现在的目标是最终得到一个结果表格式的所用工具的时间表:

tool_id | from_date_time                         | to_date_time
--------|----------------------------------------|-------------------------------
4       | 2020-02-18 12:00:00.0100000            | 2020-02-18 12:00:00.0100000
5       | 2020-02-18 12:00:00.0200000            | 2020-02-18 12:00:00.0400000
7       | 2020-02-18 12:00:00.0500000            | 2020-02-18 12:00:00.0700000
4       | 2020-02-18 12:00:00.0800000            | 2020-02-18 12:00:00.1000000

结果应该显示在plotly-dash web应用程序中,因此应该在python上下文中使用。即使有一个仅仅使用sql的解决方案,有没有更好的结合sql和python的解决方案?

l2osamch

l2osamch1#

假设“datetime”列的格式始终为 t_{int} 你可以用 STUFF 删除前2个字符,然后将该值转换为 int . 这允许您按数字排序,而不是按字典排序。然后你就可以得到 MIN 以及 MAX 用缺口和孤岛解决方案 t_ 前缀:

WITH YourTable AS(
    SELECT *
    FROM (VALUES('t_1',4),
                ('t_3',5),
                ('t_4',5),
                ('t_5',5),
                ('t_6',7),
                ('t_7',7),
                ('t_8',7),
                ('t_9',4),
                ('t_10',4),
                ('t_11',4))V(date_time,toolid)),
CTE AS(
    SELECT YT.date_time,
           YT.toolid,
           V.time_int,
           ROW_NUMBER() OVER (ORDER BY V.time_int) - 
           ROW_NUMBER() OVER (PARTITION BY YT.toolid ORDER BY V.time_int) AS Grp
    FROM YourTable YT
         CROSS APPLY(VALUES(TRY_CONVERT(int,STUFF(date_time,1,2,''))))V(time_int))
SELECT C.toolid,
       CONCAT('t_',MIN(C.time_int)) AS From_date_time,
       CONCAT('t_',MAX(C.time_int)) AS To_date_time
FROM CTE C
GROUP BY C.toolid,
         C.Grp;

编辑:未经测试,但基于op完全更改的样本数据,这现在只是一个简单的差距和孤岛问题:

WITH CTE AS(
    SELECT YT.date_time,
           YT.toolid,
           ROW_NUMBER() OVER (ORDER BY YT.date_time) - 
           ROW_NUMBER() OVER (PARTITION BY YT.toolid ORDER BY YT.date_time) AS Grp
    FROM dbo.YourTable YT)
SELECT C.toolid,
       MIN(C.date_time) AS From_date_time,
       MAX(C.date_time) AS To_date_time
FROM CTE C
GROUP BY C.toolid,
         C.Grp;

相关问题