Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie kann ich mit mysql eine wöchentliche Kohortenanalysetabelle erstellen?

Diese Abfrage ist modifiziert von der, die ich hier geschrieben habe:Kohortenanalyse in SQL

Hier ist die letzte Abfrage:

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

Der Kern davon ist also, dass wir die Benutzer und das Datum, an dem sie sich angemeldet haben, erfassen und das Datum nach Jahr-Wochen-Nummer formatieren, da wir eine wöchentliche Kohorte durchführen.

SELECT
  UserId,
  DATE_FORMAT(AddedDate, "%Y-%u") AS cohort
FROM users

Da wir nach der Kohorte gruppieren wollen, müssen wir dies in eine Unterabfrage im FROM-Teil der Abfrage einfügen.

Dann möchten wir die Zahlungsinformationen zu den Benutzern hinzufügen.

SELECT DISTINCT
  payments.UserId,
  FLOOR(DATEDIFF(payments.PaymentDate, users.AddedDate)/7) AS Offset
  FROM payments
  LEFT JOIN users ON (users.UserId = payments.UserId)

Dadurch erhalten Sie eindeutige wöchentliche Zahlungsereignisse pro Benutzer nach der Anzahl der Wochen, in denen er Benutzer war. Wir verwenden „distinct“, denn wenn ein Benutzer in einer Woche zwei Käufe getätigt hat, möchten wir dies nicht als zwei Benutzer zählen.

Wir verwenden nicht nur die Zahlungstabelle, da sich einige Benutzer möglicherweise anmelden und keine Zahlungen haben. Also wählen wir aus der Benutzertabelle aus und treten der Zahlungstabelle bei.

Sie gruppieren dann nach Wochen - u.Kohorte. Dann aggregieren Sie die Wochenzahlen, um herauszufinden, wie viele Personen in den Wochen nach ihrer Anmeldung Zahlungen getätigt haben.

Die von mir verwendete Version von mysql hatte sql_mode auf only_full_group_by gesetzt. Um die Kohortengröße zu erhalten, habe ich den Großteil der Abfrage in eine Unterabfrage gestellt, damit ich mich den Benutzern anschließen kann, um die Größe der Kohorte zu erhalten.

Weitere Überlegungen:

Das Filtern nach Wochen ist einfach. tb.cohort> Startdatum und tb.cohort

Sie können die Verwendung einer Kalendertabelle in Betracht ziehen, um Fälle abzudecken, in denen es während der Woche keine Benutzeranmeldungen gibt.

Hier ist eine Geige, bei der alles funktioniert:http://sqlfiddle.com/#!9/172dbe/ 1