SQL select 重叠行
SQL select overlap rows
我得到这个 table 操作:
+-----------+---------------------+----------+
| 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 开始,但第一个操作尚未完成。
我不知道是否有某种方法可以计算开始时间和持续时间之间的差异,并将其与下一个操作的开始时间进行比较。
您可以使用 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
);
如果您想总结重叠部分,逻辑会变得更加困难。问题是多个时间段可能会重叠。您可以在同一行中获得任何一对 - 但该对可能与另一对重叠,因此会有冗余。
您可以使用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;
可以有N个重叠。
因此,如果您期望我们可以在考虑 N 种可能性的概率的情况下创建一些查询,其中 0<=N<=M(N = 重叠数,M = 案例数),那么对于下面给出的输入案例,结果将多次显示相同的 "roomNo" 或 "theatreNo"。
+-----------+---------------------+----------+
| 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 |
+--------+---------------+----------+--------------------+
我得到这个 table 操作:
+-----------+---------------------+----------+
| 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 开始,但第一个操作尚未完成。
我不知道是否有某种方法可以计算开始时间和持续时间之间的差异,并将其与下一个操作的开始时间进行比较。
您可以使用 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
);
如果您想总结重叠部分,逻辑会变得更加困难。问题是多个时间段可能会重叠。您可以在同一行中获得任何一对 - 但该对可能与另一对重叠,因此会有冗余。
您可以使用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;
可以有N个重叠。
因此,如果您期望我们可以在考虑 N 种可能性的概率的情况下创建一些查询,其中 0<=N<=M(N = 重叠数,M = 案例数),那么对于下面给出的输入案例,结果将多次显示相同的 "roomNo" 或 "theatreNo"。
+-----------+---------------------+----------+
| 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 |
+--------+---------------+----------+--------------------+