--第一步找出用户首次登陆的日期,代码如下:
(SELECT user_id, MIN(date) AS first_login_date 
         FROM login 
         GROUP BY user_id) AS fl
--第二步找出用户次日登陆的日期,代码如下:
LEFT JOIN 
        login l
    ON 
        fl.user_id = l.user_id 
        AND l.date = DATE_ADD(fl.first_login_date, INTERVAL 1 DAY)
--第三步计算留存率,即次日登陆的用户数/首次登陆的用户数,代码如下:
ROUND(
            SUM(CASE WHEN l.date IS NOT NULL THEN 1 ELSE 0 END) 
            / NULLIF(COUNT(DISTINCT fl.user_id), 0), 3
        ) AS retention_rate
--第四步解决按日期分组计算的问题,即:
SELECT 
        fl.first_login_date, 
        ROUND(
            SUM(CASE WHEN l.date IS NOT NULL THEN 1 ELSE 0 END) 
            / NULLIF(COUNT(DISTINCT fl.user_id), 0), 3
        ) AS retention_rate
..........(第一二三步此处省略展示)
 GROUP BY 
        fl.first_login_date
--第五步,解决不满足次日留存的日期且要以0的记录显示left join为空的问题,即:
SELECT 
    distinct login.date AS wz_date,
    COALESCE(pp.retention_rate, 0) AS p
FROM 
    login
LEFT JOIN 
--完整代码连接起来如下:
SELECT 
    distinct login.date AS wz_date,
    COALESCE(pp.retention_rate, 0) AS p
FROM 
    login
LEFT JOIN (
    SELECT 
        fl.first_login_date, 
        ROUND(
            SUM(CASE WHEN l.date IS NOT NULL THEN 1 ELSE 0 END) 
            / NULLIF(COUNT(DISTINCT fl.user_id), 0), 3
        ) AS retention_rate
    FROM 
        (SELECT user_id, MIN(date) AS first_login_date 
         FROM login 
         GROUP BY user_id) AS fl
    LEFT JOIN 
        login l
    ON 
        fl.user_id = l.user_id 
        AND l.date = DATE_ADD(fl.first_login_date, INTERVAL 1 DAY)
    GROUP BY 
        fl.first_login_date
) AS pp
ON 
    login.date = pp.first_login_date;