-- Step 1: Generate all dates for the current month
WITH RECURSIVE DateSequence AS (
SELECT DATE_FORMAT(CURDATE(), '%Y-%m-01') AS dateValue -- Start from the first day of the current month
UNION ALL
SELECT DATE_ADD(dateValue, INTERVAL 1 DAY)
FROM DateSequence
WHERE DATE_ADD(dateValue, INTERVAL 1 DAY) <= LAST_DAY(CURDATE()) -- Up to the last day of the current month
)
-- Step 2, 3, and 4
SELECT ds.dateValue
FROM DateSequence ds
LEFT JOIN YourTableName t ON ds.dateValue = t.bookingDate
GROUP BY ds.dateValue
HAVING COUNT(t.id) < 5;
/* Full list of days in September 2023 based on first
* of month and number of days in month */
SELECT '2023-09-01' + INTERVAL (seq - 1) DAY AS dt
FROM seq_1_to_30;
/* Full list of days in current month */
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;
SELECT DISTINCT bookingDate
FROM bookings # your-table-name
WHERE MONTH(bookingDate) = MONTH(CURRENT_DATE()) AND YEAR(bookingDate) = YEAR(CURRENT_DATE())
GROUP BY bookingDate
HAVING COUNT(*) < 5;
4条答案
按热度按时间nbysray51#
为了更有效地实现这一点,您可以使用单个查询。以下是解决方案的分步分解:
生成当前月份的所有日期。将生成的日期与bookingDate上的预订表连接起来。按日期分组并计算每个日期的预订。筛选出有5个或更多预订的日期。你可以这样做:
将YourTableName替换为预订表的名称。此查询的结果将给予您当月少于5个预订的所有日期。
这种方法的优点是,您可以在一个查询中获得结果,从而减少多个单独查询的开销。
dnph8jn42#
有许多不同的方法来解决这个问题。
选项1(实际上不是选项)
这将只返回具有1、2、3或4个预订的
bookingDate
,因为它不知道零预订的日期。选项二
您可以在客户端应用程序中反转上述查询并重新设置结果,取消设置结果中存在的所有日期:
但是,这对我来说只是感觉“笨拙”。
备选方案3
您可以从您感兴趣的完整日期列表开始,使用MariaDB的Sequence Storage Engine生成:
显然,如果您已经有一个包含所有日期的日历表,或者要处理的连续集合,则不需要此步骤。
然后将
LEFT JOIN
转换为bookings
:这里有一个db<>fiddle玩。
**注意:**您当前的表在
bookingDate
上缺少索引:qni6mghb3#
希望这段代码能帮助你:
--取消当月少于5个预订的日期
krugob8w4#
相反,您可以找到所有 * 有 * 5个或更多预订的日期,并在客户端应用程序上实现相应的逻辑。