一段时间内的不同计数

时间:2016-04-26 10:31:32

标签: mysql datetime aggregate-functions

我有一个由user_id,action_date

组成的简单表
user_id    action_date
user_001    2016-04-15
user_002    2016-04-15
user_003    2016-04-15
user_002    2016-04-15
user_001    2016-04-15
user_004    2016-04-16
user_005    2016-04-16
user_001    2016-04-16
user_001    2016-04-16
user_001    2016-04-16

对于数据库中的每个action_date,我需要检查在从action_date算起的30天内有多少不同的用户处于活动状态。

我知道我必须为每个action_date返回30天并计算那段时间内不同的活跃用户,我尝试了类似这样的事情,但它并不像故意那样工作,因为我需要每30分钟计算一次天期进行action_date

SELECT action_date, COUNT (DISTINCT user_id) from Table_1 where user_id IN
(SELECT user_id from Table_1
WHERE action_date Between DATEADD(day,-30,action_date) and action_date)
GROUP BY action_date

2 个答案:

答案 0 :(得分:0)

SELECT action_date, COUNT (DISTINCT user_id) from Table_1 where
action_date Between DATEADD(day,-30,action_date) and action_date
GROUP BY action_date

以上查询足以获取结果

答案 1 :(得分:0)

听起来您需要为表格中的每个不同action_date添加一个数字。

所以,首先你需要一个显示行动日期的虚拟表。

  SELECT DISTINCT action_date FROM Table_1

然后,您需要以挑选30天范围的方式将该虚拟表加入原始表:

  SELECT a.action_date, b.user_id
    FROM (
           SELECT DISTINCT action_date FROM Table_1
         ) a
    LEFT JOIN Table_1 b ON b.action_date >= a.action_date - INTERVAL 29 DAY
                       AND b.action_date <= a.action_date

然后你需要聚合这个结果。

  SELECT a.action_date, COUNT(DISTINCT b.user_id) user_count
    FROM (
           SELECT DISTINCT action_date FROM Table_1
         ) a
    LEFT JOIN Table_1 b ON b.action_date >= a.action_date - INTERVAL 29 DAY
                       AND b.action_date <= a.action_date
   GROUP BY a.action_date
   ORDER BY a.action_date

我已经一步一步地写出来,希望您能看到如何使用结构化查询语言的结构化方面构建查询。

在编写这样的查询时,它也有助于对整个过程中的每个步骤进行故障排除。如果你把整个事情写出来,就很难找到问题。

- INTERVAL 29 DAY?您要求提供30天的续航时间。我已经包含了相关日期和之前的29天。)

请注意,如果您的action_dates为DATETIME项,则需要进行一些更改。

  SELECT DATE(a.action_date) action_date, 
         COUNT(DISTINCT b.user_id) user_count
    FROM (
           SELECT DISTINCT DATE(action_date) action_date FROM Table_1
         ) a
    LEFT JOIN Table_1 b ON b.action_date >= a.action_date - INTERVAL 29 DAY
                       AND b.action_date < a.action_date + INTERVAL 1 DAY
   GROUP BY DATE(a.action_date)
   ORDER BY DATE(a.action_date)

请注意当您使用DATETIME项目时,日期范围在结束日期之后的某一天午夜(但不包括<)之前运行( action_date + INTERVAL 1 DAY)。