mysql - 不计数的时间求和范围重叠两次

标签 mysql sql algorithm datetime mariadb

对于给定的用户 ID“1”和给定的一天 2018-01-02,我想计算记录的总小时数,其中可能存在重叠。

计算这个子集:

+-----+---------------------+---------------------+
| uid | time_start          | time_end            |
+-----+---------------------+---------------------+
|   1 | 2018-01-02 04:00:00 | 2018-01-02 04:30:00 |
|   1 | 2018-01-02 04:25:00 | 2018-01-02 04:35:00 |
|   1 | 2018-01-02 04:55:00 | 2018-01-02 05:15:00 |
+-----+---------------------+---------------------+

结果时间应该是:00:55

最佳答案

MariaDB 10.3 具有窗口函数和 CTE,因此您可以使用它们来生成结果。 CTE 通过将当前 time_start 与当天的最大先前 time_end 进行比较并取其最大(最大)值,然后进行查询,从而消除 session 时间的重叠只需 SUM 每次 session 时间,按用户 ID 和日期分组。请注意,如果一个 session 与另一个 session 完全重叠,则 CTE 会将 startend 时间设置为重叠 session 的 end 时间,从而有效 session 长度为 0。我扩展了我的演示以包含这样的场景,以及多个重叠 session :

WITH sessions AS 
    (SELECT uid,
            GREATEST(time_start, COALESCE(MAX(time_end) OVER (PARTITION BY DATE(time_start) ORDER BY time_start ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), '2000-01-01')) AS start,
            MAX(time_end) OVER (PARTITION BY DATE(time_start) ORDER BY time_start ROWS UNBOUNDED PRECEDING)  AS end
            FROM sessions)
SELECT uid, DATE(start) AS `date`, SEC_TO_TIME(SUM(TO_SECONDS(end) - TO_SECONDS(start))) AS totaltime
FROM sessions
GROUP BY uid, `date`

输出:

uid     date        totaltime
1       2018-01-02  00:55:00
1       2018-01-03  01:00:00
1       2018-01-04  01:15:00

Demo on dbfiddle

关于mysql - 不计数的时间求和范围重叠两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54545433/

相关文章:

具有相同列名的 MySQL 连接表

c# - 是否可以在 Linq 的 1 个 join 语句中添加多个 'on'

sql - 在 like 子句中搜索通配符 '%%' 的编译器成本

sql - 我怎样才能通过对大表的查询来加快这个计数+分组的速度?

java - 在android中的给定字符串数组中搜索子字符串

mysql - 如何使用 JDBC 在数据库的某些表中搜索字符串?

mysql - 可以在mysql上将double和date存储在varchar中吗

mysql - 如何在mysql中使用REGEXP选择结果,不包含字符串

algorithm - 线性时间算法的总和是线性时间?

algorithm - 来自点集的边界点