Tento dotaz je upraven od dotazu, který jsem napsal zde:Kohortová analýza v SQL
Zde je poslední dotaz:
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
Takže jádrem toho je, že vezmeme uživatele a datum, kdy se zaregistrovali, a naformátujeme datum podle čísla rok-týden, protože děláme týdenní kohortu.
SELECT
UserId,
DATE_FORMAT(AddedDate, "%Y-%u") AS cohort
FROM users
Protože chceme seskupit podle kohorty, musíme to vložit do poddotazu v části FROM dotazu.
Poté se chceme připojit k platebním údajům o uživatelích.
SELECT DISTINCT
payments.UserId,
FLOOR(DATEDIFF(payments.PaymentDate, users.AddedDate)/7) AS Offset
FROM payments
LEFT JOIN users ON (users.UserId = payments.UserId)
Tím získáte jedinečné týdenní platební události na uživatele podle počtu týdnů, kdy byl uživatelem. Používáme odlišné, protože pokud uživatel provedl 2 nákupy během jednoho týdne, nechceme to počítat jako dva uživatele.
Nepoužíváme pouze tabulku plateb, protože někteří uživatelé se mohou zaregistrovat a nemají platby. Vybíráme tedy z tabulky uživatelů a připojujeme se k tabulce plateb.
Ty pak seskupují podle týdne – u.cohort. Poté agregujete čísla týdnů, abyste zjistili, kolik lidí provedlo platby v týdnech poté, co se zaregistrovali.
Verze mysql, kterou jsem použil, měla sql_mode nastavenou na only_full_group_by. Abych získal velikost kohorty, vložil jsem většinu dotazu do dílčího dotazu, abych se mohl připojit k uživatelům a získat velikost kohorty.
Další úvahy:
Filtrování podle týdnů je jednoduché. tb.cohort> počáteční datum a tb.cohort
Možná budete chtít zvážit použití tabulky kalendáře k pokrytí případů, kdy během týdne nejsou žádné registrace uživatelů.
Zde je návod, jak vše funguje:http://sqlfiddle.com/#!9/172dbe/ 1