Denne forespørgsel er modificeret fra den, jeg skrev her:Kohorteanalyse i SQL
Her er den sidste forespørgsel:
SELECT
STR_TO_DATE(CONCAT(tb.cohort, ' Monday'), '%X-%V %W') as date,
size,
w1,
w2,
w3,
w4,
w5,
w6,
w7
FROM (
SELECT u.cohort,
IFNULL(SUM(s.Offset = 0), 0) w1,
IFNULL(SUM(s.Offset = 1), 0) w2,
IFNULL(SUM(s.Offset = 2), 0) w3,
IFNULL(SUM(s.Offset = 3), 0) w4,
IFNULL(SUM(s.Offset = 4), 0) w5,
IFNULL(SUM(s.Offset = 5), 0) w6,
IFNULL(SUM(s.Offset = 6), 0) w7
FROM (
SELECT
UserId,
DATE_FORMAT(AddedDate, "%Y-%u") AS cohort
FROM users
) as u
LEFT JOIN (
SELECT DISTINCT
payments.UserId,
FLOOR(DATEDIFF(payments.PaymentDate, users.AddedDate)/7) AS Offset
FROM payments
LEFT JOIN users ON (users.UserId = payments.UserId)
) as s ON s.UserId = u.UserId
GROUP BY u.cohort
) as tb
LEFT JOIN (
SELECT DATE_FORMAT(AddedDate, "%Y-%u") dt, COUNT(*) size FROM users GROUP BY dt
) size ON tb.cohort = size.dt
Så kernen i dette er, at vi griber brugerne og den dato, de tilmeldte sig, og formaterer datoen efter år-ugenummer, da vi laver en ugentlig kohorte.
SELECT
UserId,
DATE_FORMAT(AddedDate, "%Y-%u") AS cohort
FROM users
Da vi ønsker at gruppere efter kohorten, skal vi indsætte dette i en underforespørgsel i FROM-delen af forespørgslen.
Så vil vi tilslutte os betalingsoplysningerne på brugerne.
SELECT DISTINCT
payments.UserId,
FLOOR(DATEDIFF(payments.PaymentDate, users.AddedDate)/7) AS Offset
FROM payments
LEFT JOIN users ON (users.UserId = payments.UserId)
Dette vil få unikke ugentlige betalingsbegivenheder pr. bruger efter det antal uger, de har været bruger. Vi bruger distinct, fordi hvis en bruger foretog 2 køb på en uge, ønsker vi ikke at tælle det som to brugere.
Vi bruger ikke kun betalingstabellen, fordi nogle brugere kan tilmelde sig og ikke have betalinger. Så vi vælger fra brugertabellen og slutter os til betalingstabellen.
Man grupperer så efter uge - u.kohorte. Derefter samler du ugenumrene for at finde ud af, hvor mange personer der har foretaget betalinger ugerne efter, de har tilmeldt sig.
Den version af mysql, jeg brugte, havde sql_mode sat til only_full_group_by. Så for at få kohortestørrelsen lagde jeg størstedelen af forespørgslen i underforespørgsel, så jeg kunne slutte mig til brugerne for at få kohortens størrelse.
Yderligere overvejelser:
Filtrer efter uger er enkelt. tb.cohort> startdato og tb.cohort
Du vil måske overveje at bruge en kalendertabel til at dække tilfælde, hvor der ikke er nogen brugertilmeldinger i løbet af ugen.
Her er en violin med alt, der fungerer:http://sqlfiddle.com/#!9/172dbe/ 1