Mysql
 sql >> база данни >  >> RDS >> Mysql

Как мога да създам седмична таблица за кохортен анализ с помощта на mysql?

Тази заявка е променена от тази, която написах тук:Кохортен анализ в SQL

Ето последната заявка:

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

И така, сърцевината на това е, че вземаме потребителите и датата, на която са се регистрирали, и форматираме датата по номер година-седмица, тъй като правим седмична кохорта.

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

Тъй като искаме да групираме по кохортата, трябва да поставим това в подзаявка в частта FROM на заявката.

След това искаме да присъединим информацията за плащане на потребителите.

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

Това ще получи уникални седмични плащания на потребител по броя на седмиците, през които е бил потребител. Използваме различни, защото ако потребител направи 2 покупки за една седмица, не искаме да ги броим като двама потребители.

Ние не използваме само таблицата за плащания, защото някои потребители може да се регистрират и да нямат плащания. Затова избираме от таблицата на потребителите и се присъединяваме към таблицата за плащания.

След това групирате по седмица - u.cohort. След това обобщавате числата за седмиците, за да разберете колко хора са направили плащания в седмиците след като са се регистрирали.

Версията на mysql, която използвах, имаше sql_mode, зададен на only_full_group_by. Така че, за да получа размера на кохортата, поставих по-голямата част от заявката в подзаявка, за да мога да се присъединя към потребителите, за да получа размера на кохортата.

Допълнителни съображения:

Филтрирането по седмици е лесно. tb.cohort> начална дата и tb.cohort <крайна дата, където началната и крайната дата са форматирани с "%Y-%u". За да направите заявката по-ефективна, вероятно ще искате да филтрирате и събития за плащане, които не попадат в диапазона от време, така че да не се присъединявате към данни, от които не се нуждаете.

Може да помислите за използването на таблица с календар, за да покриете случаите, при които няма регистрирани потребители през седмицата.

Ето една цигулка с всичко, което работи:http://sqlfiddle.com/#!9/172dbe/ 1



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. php POST формуляр за актуализиране на динамична променлива

  2. Mysql Не може да се осъществи връзка, защото целевата машина активно я отказва

  3. Mysql търсене на низ и число с помощта на MATCH() AGAINST()

  4. MySQL пропуска първите 10 резултата

  5. Как да свържа IntelliJ с локален MySQL?