Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment puis-je créer un tableau d'analyse de cohorte hebdomadaire à l'aide de mysql ?

Cette requête est modifiée par rapport à celle que j'ai écrite ici :Analyse de cohorte en SQL

Voici la requête finale :

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

Donc, le cœur de ceci est que nous saisissons les utilisateurs et la date à laquelle ils se sont inscrits et formatons la date par numéro d'année-semaine, puisque nous faisons une cohorte hebdomadaire.

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

Puisque nous voulons regrouper par cohorte, nous devons mettre cela dans une sous-requête dans la partie FROM de la requête.

Ensuite, nous voulons joindre les informations de paiement sur les utilisateurs.

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

Cela obtiendra des événements de paiement hebdomadaires uniques par utilisateur en fonction du nombre de semaines d'utilisation. Nous utilisons distinct car si un utilisateur a effectué 2 achats en une semaine, nous ne voulons pas compter cela comme deux utilisateurs.

Nous n'utilisons pas seulement le tableau des paiements, car certains utilisateurs peuvent s'inscrire et ne pas avoir de paiements. Nous sélectionnons donc dans la table des utilisateurs et rejoignons la table des paiements.

Vous regroupez ensuite à la semaine - u.cohort. Ensuite, vous regroupez les chiffres de la semaine pour savoir combien de personnes ont effectué des paiements dans les semaines suivant leur inscription.

La version de mysql que j'ai utilisée avait sql_mode défini sur only_full_group_by. Donc, pour obtenir la taille de la cohorte, j'ai mis l'essentiel de la requête en sous-requête afin de pouvoir rejoindre les utilisateurs pour obtenir la taille de la cohorte.

Autres considérations :

Filtrer par semaines est simple. tb.cohort> date de début et tb.cohort

Vous pouvez envisager d'utiliser un tableau de calendrier pour couvrir les cas où aucun utilisateur ne s'inscrit pendant la semaine.

Voici un violon avec tout ce qui fonctionne :http://sqlfiddle.com/#!9/172dbe/ 1