I am trying to fetch data, to show the user a overview of how many session the person have had. The table is structured in a similar way:
session_id | User | start_time |
---|---|---|
1 | User A | 2022-01-01 |
2 | User A | 2023-01-02 |
3 | User A | 2023-03-15 |
4 | User A | 2023-03-16 |
5 | User A | 2023-03-02 |
6 | User A | 2023-03-10 |
Is it possible to construct a query, where i get the count of session for each month, starting from the first session the user have had, until the current month. The output i would like, could be similar to the example below.
Month | COUNT(session_id) |
---|---|
Jan-22 | 1 |
Feb-22 | 0 |
...-22 | 0 |
Dec-22 | 0 |
Jan-23 | 1 |
Feb-23 | 0 |
Mar-23 | 4 |
Apr-23 | 0 |
I have tried to create the following query:
SELECT DATE_FORMAT(DATE_ADD(min_month, INTERVAL m.n MONTH), '%Y-%m') as month,
COALESCE(COUNT(c.consumption), 0) as total_consumption
FROM
(SELECT DATE_FORMAT(MIN(start_time), '%Y-%m-01') as min_month
FROM session
WHERE user_id = 'sGcO42wMx1ZHXwZpZH3KWwWXzd13') as start_month
CROSS JOIN
(SELECT n
FROM (SELECT 0 n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) as n) as m
LEFT JOIN session as c ON DATE_FORMAT(c.start_time, '%Y-%m') = DATE_FORMAT(DATE_ADD(start_month.min_month, INTERVAL m.n MONTH), '%Y-%m')
AND c.user_id = 'sGcO42wMx1ZHXwZpZH3KWwWXzd13'
GROUP BY month
ORDER BY month ASC;
But the result comming back only include 10 months:
Month | COUNT(session_id) |
---|---|
Jan-22 | 1 |
...-22 | 0 |
Oct-22 | 0 |
With help of this result from StackExchange: Generate Dates between Date Ranges in mysql was i able to figure out how to get the right result.
By creating a recursive table named Date_Ranges, i was able to create table based on the first session a user had, until the current day. With this i made a LEFT JOIN to, get the number of session from the original table.
The expected query therefore was:
WITH recursive Date_Ranges AS (
SELECT (SELECT start_time FROM user.session WHERE user_id = 'sGcO42wMx1ZHXwZpZH3KWwWXzd13' ORDER BY start_time ASC LIMIT 1) AS d
UNION ALL
SELECT d + interval 1 month
FROM Date_Ranges
WHERE d < NOW()
)
SELECT DATE_FORMAT(dates.d, '%b-%y') AS Month, COUNT(s.session_id) AS Count
FROM Date_Ranges dates
LEFT JOIN user.session s ON DATE_FORMAT(s.start_time, '%Y-%m') = DATE_FORMAT(dates.d, '%Y-%m') AND s.user_id = 'sGcO42wMx1ZHXwZpZH3KWwWXzd13'
GROUP BY Month;
And produced the table response i wanted.