【问题标题】:SQL select overlap rowsSQL 选择重叠行
【发布时间】:2019-12-10 12:57:48
【问题描述】:

我得到了这个表操作:

+-----------+---------------------+----------+
| theatreNo |    startDateTime    | duration |
+-----------+---------------------+----------+
|         1 | 2019-05-12 09:30:00 | 04:50:00 |
|         3 | 2019-05-17 15:05:00 | 02:00:00 |
|         3 | 2019-05-17 16:05:00 | 03:00:00 |
+-----------+---------------------+----------+

我正在尝试查找我们是否有两个操作重叠的剧院,它应该输出以下内容:

+--------+---------------+----------+----------+
| roomNo | startDateTime | firstOp  | secondOp |
+--------+---------------+----------+----------+
|      3 | 2019-05-17    | 15:05:00 | 16:05:00 |
+--------+---------------+----------+----------+

这是重叠的,因为一个手术从 15:05 开始,持续时间为 2 小时,而同一个剧院的另一个手术从 16:05 开始,但第一个手术还没有结束。

我不知道是否有某种方法可以计算开始时间和持续时间之间的差异,并将其与下一个操作的开始时间进行比较。

【问题讨论】:

标签: mysql sql database overlap


【解决方案1】:

您可以使用ADDTIME() 查找manual here。 在手册中您还可以找到DATE()TIME()

SELECT o1.theatreNo as roomNo,
       DATE(o1.startDateTime) as startDateTime, 
       TIME(o1.startDateTime) as firstOp, 
       TIME(o2.startDateTime) as secondOp
FROM operation o1
JOIN operation o2 ON o1.theatreNo = o2.theatreNo
WHERE o1.startDateTime < ADDTIME(o2.startDateTime,o2.duration)
AND ADDTIME(o1.startDateTime,o1.duration) > o2.startDateTime
AND o1.startDateTime < o2.startDateTime;

DEMO

【讨论】:

    【解决方案2】:

    您可以使用join 获取同一行中的重叠对:

    select o.*, o2.*
    from operation o join
         operation o2
         on o2.theatreNo = o.theatreNo and
            o2.startDateTime < o.startDateTime + o.duration and
            o2.startDateTime + o2.duration > o.startDateTime and
            (o2.startDateTime <> o.startDateTime or
             o2.duration <> o.duration
            );
    

    如果您想总结重叠部分,逻辑会变得更加困难。问题是多个时间段可能重叠。您可以在同一行中获得任何一对 - 但该对可能与另一对重叠,因此会有冗余。

    【讨论】:

    • 这个查询在我的演示中不起作用。用o2.startDateTime + o2.duration &gt; o.startDateTime AND o2.startDateTime &lt; o.startDateTime; 改变最后几行就可以了
    • @AlbertoMoro 。 . .这不是确切的逻辑。我修复了查询。
    【解决方案3】:

    可以有 N 个重叠。

    因此,如果您期望我们可以在相同的情况下创建一些查询,考虑到 0

    +-----------+---------------------+----------+
    | theatreNo |    startDateTime    | duration |
    +-----------+---------------------+----------+
    |         1 | 2019-05-12 09:30:00 | 04:50:00 |
    |         3 | 2019-05-17 15:05:00 | 02:00:00 |
    |         3 | 2019-05-17 16:05:00 | 03:00:00 |
    |         3 | 2019-05-17 17:05:00 | 03:00:00 |
    +-----------+---------------------+----------+
    

    它会给出以下答案

    +--------+---------------+----------+----------+
    | roomNo | startDateTime | firstOp  | secondOp |
    +--------+---------------+----------+----------+
    |      3 | 2019-05-17    | 15:05:00 | 16:05:00 |
    |      3 | 2019-05-17    | 16:05:00 | 17:05:00 |
    +--------+---------------+----------+----------+
    

    为避免这种情况,您可以使用以下显示所有重叠的查询

    SELECT o1.theatreNo as roomNo,
           DATE(o1.startDateTime) as startDateTime, 
           TIME(o1.startDateTime) as firstOp, 
           GROUP_CONCAT(TIME(o2.startDateTime)) as allOp
    FROM operation o1
    JOIN operation o2 ON o1.theatreNo = o2.theatreNo
    WHERE o1.startDateTime < ADDTIME(o2.startDateTime,o2.duration)
    AND ADDTIME(o1.startDateTime,o1.duration) > o2.startDateTime
    AND o1.startDateTime < o2.startDateTime;
    

    这会给你以下结果

    +--------+---------------+----------+--------------------+
    | roomNo | startDateTime | firstOp  | allOp              |
    +--------+---------------+----------+--------------------+
    |      3 | 2019-05-17    | 15:05:00 | 16:05:00, 17:05:00 |
    +--------+---------------+----------+--------------------+
    

    DEMO

    【讨论】:

      猜你喜欢
      • 2022-01-25
      • 2013-01-12
      • 1970-01-01
      • 1970-01-01
      • 2022-06-13
      • 1970-01-01
      • 2020-10-16
      • 2011-12-06
      • 1970-01-01
      相关资源
      最近更新 更多