sql >> Database teknologi >  >> RDS >> Mysql

Hvordan kan jeg oprette en ugentlig kohorteanalysetabel ved hjælp af mysql?

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



  1. LIKE og NULL i WHERE-sætning i SQL

  2. MySQL LOAD DATA LOKAL INFILE eksempel i python?

  3. MySQL-forespørgsel med flere tabeller

  4. Internaler i de syv SQL Server-sorteringer – Del 1