有很多不同的方法来解决这个问题。
选项1(实际上不是一个选项)
SELECT bookingDate
FROM bookings
WHERE bookingDate BETWEEN '2023-09-01' AND '2023-09-30'
GROUP BY bookingDate
HAVING COUNT(*) < 5;
这将仅返回具有1、2、3或4个预订的
bookingDate
,因为它不知道没有预订的日期。
选项2
您可以反转上述查询,并在客户端应用程序中迭代结果,取消所有存在于结果中的日期。
SELECT bookingDate
FROM bookings
GROUP BY bookingDate
HAVING COUNT(*) >= 5;
但是,对我来说,那只是感觉笨拙。选项3,你可以使用MariaDB的
Sequence Storage Engine生成你感兴趣的全部日期列表开始。
SELECT '2023-09-01' + INTERVAL (seq - 1) DAY AS dt
FROM seq_1_to_30;
SELECT CURRENT_DATE - INTERVAL (DAY(CURRENT_DATE) - 1) DAY + INTERVAL (seq - 1) DAY AS dt
FROM seq_1_to_31
WHERE seq <= DAY(LAST_DAY(CURRENT_DATE));
显然,如果您已经有一个包含所有日期的日历表或连续的日期集合,那么就不需要进行这一步骤。
然后,将其与您的预订表进行左连接。
SELECT s.dt, COUNT(b.id) AS num_bookings
FROM (
SELECT '2023-09-01' + INTERVAL (seq - 1) DAY AS dt
FROM seq_1_to_30
) s
LEFT JOIN bookings b
ON s.dt = b.bookingDate
GROUP BY s.dt
HAVING num_bookings < 5;
这是一个可以玩耍的
db<>fiddle链接。
注意:您当前的表缺少对bookingDate字段的索引。
ALTER TABLE bookings ADD INDEX idx_booking_date (bookingDate);
GROUP BY
和HAVING
子句来计算每个日期的预订数量并过滤结果。 - undefinedLEFT JOIN
来完成。在https://mysql.rjweb.org/doc.php/index_cookbook_mysql#sequence中可以看到一个示例。 - undefined