I have a table with the following schema:
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`bookingDate` date NOT NULL,
PRIMARY KEY(`id`)
I need to get all dates of the current month where there’s less than 5 bookings. (meaning where less than 5 rows exist where bookingDate == date)
I tried iterating over every day of the month individually, but for performance reasons it really doesn’t make sense to perform +/- 30 queries for every month.
3
Answers
Hope this helps:
There are many different ways of tackling this.
This is not one of them:
This will only return
bookingDate
s with 1, 2, 3 or 4 bookings, as it does not know about dates with zero bookings.You could invert the above query and iterate over the result in your client application, unsetting all dates that exist in the result:
But, that just feels clunky to me.
You could start with the full list of days you are interested in, generated using MariaDB’s Sequence Storage Engine:
Obviously, there is no need for this step if you already have a calendar table with all dates, or a contiguous set to work with.
And then
LEFT JOIN
to yourbookings
:Here’s a db<>fiddle to play with.
Note: Your current table is lacking an index on
bookingDate
:To achieve this more efficiently, you can use a single query. Here’s a step-by-step breakdown of the solution:
Generate all dates for the current month.
LEFT JOIN the generated dates with the booking table on the bookingDate.
Group by the date and count the bookings for each date.
Filter out the dates that have 5 or more bookings.
Here’s how you can do it:
Replace YourTableName with the name of your booking table. The result of this query will give you all the dates of the current month where there are less than 5 bookings.
The advantage of this approach is that you get your result in one query, reducing the overhead of multiple individual queries.