With the help of Rick to look for pivot table I was able to create the final query as described in this post: https://stackoverflow.com/questions/7674786/mysql-pivot-table
Query for a 6 months analysis:
SELECT
YEAR(registered), MONTH(registered), COUNT(*) as total,
COUNT(
CASE
WHEN lastLogin >= DATE_ADD(DATE_SUB(DATE(registered), INTERVAL DAYOFMONTH(registered) - 1 DAY), INTERVAL 1 MONTH)
THEN 1
ELSE NULL
END
) AS month1,
COUNT(
CASE
WHEN lastLogin >= DATE_ADD(DATE_SUB(DATE(registered), INTERVAL DAYOFMONTH(registered) - 1 DAY), INTERVAL 2 MONTH)
THEN 1
ELSE NULL
END
) AS month2,
COUNT(
CASE
WHEN lastLogin >= DATE_ADD(DATE_SUB(DATE(registered), INTERVAL DAYOFMONTH(registered) - 1 DAY), INTERVAL 3 MONTH)
THEN 1
ELSE NULL
END
) AS month3,
COUNT(
CASE
WHEN lastLogin >= DATE_ADD(DATE_SUB(DATE(registered), INTERVAL DAYOFMONTH(registered) - 1 DAY), INTERVAL 4 MONTH)
THEN 1
ELSE NULL
END
) AS month4,
COUNT(
CASE
WHEN lastLogin >= DATE_ADD(DATE_SUB(DATE(registered), INTERVAL DAYOFMONTH(registered) - 1 DAY), INTERVAL 5 MONTH)
THEN 1
ELSE NULL
END
) AS month5,
COUNT(
CASE
WHEN lastLogin >= DATE_ADD(DATE_SUB(DATE(registered), INTERVAL DAYOFMONTH(registered) - 1 DAY), INTERVAL 6 MONTH)
THEN 1
ELSE NULL
END
) AS month6
FROM
user
WHERE
registered >= "2015-01-01"
GROUP BY YEAR(registered) , MONTH(registered)
The part DATE_SUB(DATE(registered), INTERVAL DAYOFMONTH(registered) - 1 DAY)
will return the first of a month to make sure the analysis is based on calendar months. I am not sure if it could be simplified. I was looking at STR_TO_DATE(LEFT(registered, 7), "%y-%m")
but I was reading working on Strings is slower and should be avoided.
Here is some exemplary output of the query:
year, month, total , month1, month2, month3, month4, month5, month6
'2015', '1', '14776', '4302', '3225', '2827', '2547', '2330', '2163'
'2015', '2', '12162', '3859', '2866', '2465', '2259', '2046', '1890'
'2015', '3', '10770', '3831', '2841', '2507', '2288', '2135', '1987'
'2015', '4', '15685', '3731', '2641', '2273', '2045', '1872', '1730'
'2015', '5', '18130', '3686', '2403', '1993', '1744', '1528', '1363'