I have a query which is supposed to fetch data added to a table in the last 14 days. Now the issue is that the table might not have data for a particular date or might not have data at all. But I want to have a scenario where the result could have all dates from the last 14 dates and return the result count if available or return 0 as default.
My query currently:
SELECT b.created_at day, COUNT(b.id) count
FROM businesses b
WHERE b.created_at BETWEEN SUBDATE(NOW(), 14) AND NOW()
GROUP BY b.created_at
Sample table:
id created_at
1 2021-11-20
2 2021-11-20
3 2021-11-19
4 2021-11-18
5 2021-11-17
The above query ran on the above table will produce something like this:
day count
2021-11-20 2
2021-11-19 1
2021-11-18 1
2021-11-17 1
What i wish to achieve should look like this; using the current date as 2021-11-22
day count
2021-11-22 0
2021-11-21 0
2021-11-20 2
2021-11-19 1
2021-11-18 1
2021-11-17 1
2021-11-16 0
2021-11-15 0
2021-11-14 0
2021-11-13 0
2021-11-12 0
2021-11-11 0
2021-11-10 0
2021-11-09 0
From the above query, the WHERE clause checks for created_at
values between the current date and a 14 days interval backwards. The table obviously won't have data for all of the dates which is why i wish to return 0 for such dates. How to go about this please. Thanks.
CodePudding user response:
I suppose created_at
is DATE
not DATETIME
, otherwise DATE(created_at)
should be used.
add a helper table with running number 0 - 13 to generate rows with missing data.
SELECT DATE(NOW()) - INTERVAL n.diff DAY AS day, COALESCE(d.counts, 0)
FROM (
SELECT 0 diff UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12 UNION SELECT 13
) n
LEFT JOIN (
SELECT b.created_at, COUNT(b.id) counts
FROM businesses b
WHERE b.created_at BETWEEN SUBDATE(NOW(), 14) AND NOW()
GROUP BY b.created_at
) d ON d.created_at = DATE(NOW()) - INTERVAL n.diff DAY
ORDER BY day