我正在尝试选择 MySQL 数据库中约会之间的前十个空时隙。
约会表基本上有 3 个字段:约会_id INT、startDateTime DATETIME 和 endDateTime DATETIME。
我们可以想象一些这样的数据(为简单起见,我将日期部分排除在日期时间之外,因此让我们考虑这些时间是在同一天)。数据也按 startDateTime 排序:
4 | 09:15:00 | 09:30:00
5 | 09:30:00 | 09:45:00
8 | 10:00:00 | 10:15:00
3 | 10:30:00 | 10:45:00
7 | 10:45:00 | 11:00:00
2 | 11:00:00 | 11:15:00
1 | 11:30:00 | 12:00:00
所以我的目标是提取:
00:00:00 | 09:15:00
09:45:00 | 10:00:00
10:15:00 | 10:30:00
11:15:00 | 11:30:00
最终这样做:
SET @myStart = '2012-10-01 09:15:00';
SET @myEnd = NULL;
SET @prevEnd = NULL;
SELECT a.endDateTime, b.startDateTime, @myStart := a.endDateTime
FROM appointment a, appointment b, (
SELECT @myEnd := min(c.startDateTime)
FROM appointment c
WHERE c.startDateTime >= @myStart
ORDER BY startDateTime ASC
) as var ,
(SELECT @prevEnd := NULL) v
WHERE a.appointment_id = (
SELECT appointment_id
FROM (
SELECT appointment_id, max(endDateTime), @prevEnd := endDateTime
FROM appointment d
WHERE (@prevEnd IS NULL OR @prevEnd = d.startDateTime)
AND d.startDateTime >= @myEnd
) as z
)
AND b.startDateTime > a.endDateTime
ORDER BY b.startDateTime ASC LIMIT 0,10;
这不会返回任何结果。我猜这是因为我的用户定义变量的初始化不正确(刚刚发现它们,我可能完全错误地使用它们)。
如果我只运行第一个子查询,其目标是在@myStart 之后的第一次约会时初始化@myEnd,我可以看到它实际上返回 09:15:00。
第二个子查询(SELECT @prevEnd := NULL) v
旨在每次在主查询中选择一行时将 @prevEnd 设置回 NULL。我不太确定它是否像那样工作......
最后一个子查询的意思是,从一个空的@prevEnd 和一个初始化的@myEnd 开始,用来选择之后有间隔的约会。如果与查询的其余部分分开,我可以验证它是否也有效。
您对我可以做些什么来修复查询,我可以/应该如何做,或者它是否可能有任何建议?
首先十分感谢。
编辑:我已经像这样编辑它:
SELECT *
FROM (
SELECT COALESCE( s1.endDateTime, '0000-00-00 00:00:00' ) AS myStart, MIN( s2.startDateTime ) AS minSucc
FROM appointment s1
RIGHT JOIN appointment s2 ON s1.endDateTime < s2.startDateTime
AND s1.radiologyroom_id = s2.radiologyroom_id
WHERE s1.startDateTime >= '2012-10-01 00:00:00'
AND s1.radiologyroom_id =174
AND s1.endDateTime < '2013-01-01 00:00:00'
GROUP BY myStart
ORDER BY s1.startDateTime
)s
WHERE NOT
EXISTS (
SELECT NULL
FROM appointment
WHERE startDateTime >= myStart
AND endDateTime <= minSucc
AND radiologyroom_id =174
ORDER BY startDateTime
)
它在 14.6 秒内从 6530 条记录中检索出 369 行