用于队列分析的MySql查询

时间:2016-02-09 10:37:03

标签: php mysql symfony

我正在使用MySql和Symfony2。我需要建立队列分析表。我需要比较每个群组中有多少用户在注册后每周至少登录一次网站。我试图做的是按周计算注册用户数,基本上这些都是我的同伴。

 SELECT DATE_FORMAT(date_added,'%d %b %y') as reg_date, COUNT(*) AS user_count 
 FROM user 
 WHERE date_added>='2016-02-01' AND date_added<=NOW() 
 GROUP BY WEEK(date_added)

此查询获取按周登录到网站的不同用户。

 SELECT WEEK(login_date) AS week, COUNT(DISTINCT user_id) AS user_count
 FROM user_log
 WHERE login_date>='2016-02-01' AND login_date<=NOW()
 GROUP BY WEEK(login_date)

我的问题:我无法弄清楚如何按群组对登录用户进行分组,并按周比较同类群组。我希望我能清楚说明问题。英语不是我的第一语言。感谢。

示例数据:

 user table 

 id      | date_added (in WEEK() format) 
 A       | 1  
 B       | 1  
 C       | 1   
 D       | 2
 E       | 2
 F       | 2
 G       | 2
 ------------

 user_log table 
 user_id | login_date (in WEEK() format)
 A       | 1   
 B       | 1
 B       | 1
 A       | 2
 D       | 2
 A       | 2   
 D       | 2
 E       | 2

预期表格。群组1 - 在第1周注册的用户,群组中的2周等。大小 - 注册用户的数量。第1周 - 注册后第一周登录网站的用户数量,第2周 - 注册后第二周登录网站的用户数量

 Cohort     size    Week1   Week2
 Cohort 1 |  3   |    2   |    1   |    
 Cohort 2 |  4   |    2   |    -   |

1 个答案:

答案 0 :(得分:0)

这是借鉴了我对@Andriy M对这个问题的回答的修改:Cohort analysis in SQL

此查询在注册后按周获得唯一的用户登录。

SELECT DISTINCT
    user_id,
    FLOOR(DATEDIFF(user_log.login_date, user.date_added)/7) AS Offset
    FROM user_log
    LEFT JOIN user ON (user.id = user_log.user_id)
    WHERE user_log.login_date >= CURDATE() - INTERVAL 14 DAY

此查询获取过去14天内创建的所有用户,并将日期格式化为他们注册的一周:

 SELECT
    id,
    DATE_FORMAT(date_added, "%Y-%u") AS cohort
  FROM user
  WHERE date_added >= CURDATE() - INTERVAL 14 DAY

我们可以将这两个查询放在一起,以便在注册后找到有多少人回来的表格:

SELECT STR_TO_DATE(CONCAT(u.cohort, ' Monday'), '%X-%V %W') as date,
  SUM(s.Offset = 0) AS size,
  SUM(s.Offset = 1) AS Week1,
  SUM(s.Offset = 2) AS Week2
FROM (
 SELECT
    id,
    DATE_FORMAT(date_added, "%Y-%u") AS cohort
  FROM user
  WHERE date_added >= CURDATE() - INTERVAL 21 DAY
) as u
LEFT JOIN (
    SELECT DISTINCT
    user_id,
    FLOOR(DATEDIFF(user_log.login_date, user.date_added)/7) AS Offset
    FROM user_log
    LEFT JOIN user ON (user.id = user_log.user_id)
    WHERE user_log.login_date >= CURDATE() - INTERVAL 21 DAY
) as s
ON s.user_id = u.id
GROUP BY u.cohort
ORDER BY u.cohort

由于我们不计算在一周内注册的人数,因此我们假设他们在注册的那一周以租约方式记录一次,以便为尺寸列提供准确的结果。

此外,你必须重做这个以获得队列的号码而不是日期,但我发现日期更有帮助。

此外,您可以将此延长至更长时间 - 您必须在两个子查询中更改INTERVAL之后的天数,并且您可以在主select语句中添加更多行以获得更多周。