I need to generate data to build some charts.
The current results have missing data points and I'd like them to fill them with 0
's.
Data is stored in MySQL 8. Simplified data sample & query fiddle here.
The query I currently have is
SELECT
currency,
GROUP_CONCAT(volume) AS volume
FROM (
SELECT
DATE(t.created_at) AS created_at,
t.currency AS currency,
SUM(t.amount) AS volume
FROM
transactions AS t
WHERE (t.created_at BETWEEN @start AND @end)
GROUP BY
created_at,
currency
ORDER BY
created_at,
currency) r
GROUP BY
currency
which creates this result set:
currency | volume |
---|---|
AUD | 27553.52,13395.20,18349.51,3773.29,… |
BRL | 272.45,… |
CAD | 14738.08,7372.58,5926.08,7877.14,… |
CHF | 320.00,27.00,47.00,27.00,… |
EUR | 888.62,2806.27,4445.30,805.93,… |
GBP | 48588.64,37266.79,27275.01,13981.08,… |
MXN | 10.00,16298.00,1900.00,… |
SEK | 497.00,497.00,1491.00,… |
USD | 374660.85,347793.84,523608.81,839710.22,… |
Where I need help:
- How can I fill the mising data points with
0
? - Let's assume the worst and at some point there are no transactions for any of the currencies for a day (or multiple days). How can I fill those missing data points?
I've read quite a few posts about WITH RECURSIVE
and calendar tables
but I can't wrap my head around it.
I'd appreciate any help/pointers. Thank you!
Update 1
@Akina's answer basically does what I asked for (thank you!) but: the query takes ages to complete.
The transactions
table currently holds ~4m rows of data. A monthly resultset averages to roughly ~270k rows. Amogst others, there are indexes on currency
, created_at
and a compound index for created_at,currency
.
Update 2
Something is off with my indexes. If I
LEFT JOIN transactions AS t FORCE INDEX(created_at) ...
then the query completes in ~15s, regardless if I set the date range to a month or 6 months.
Best Answer
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=96b9434f665ea819c1fc2be225c403d4