选择在两个不同日期内执行操作的用户,其中一天在上周内

时间:2017-06-29 21:04:17

标签: mysql sql

给出一个看起来像这样的event_stream

*----*--------*---------*-------------*
| id | action | user_id | occurred_on |
*----*--------*---------*-------------*

users表看起来像这样(简化)

*----*-------*
| id | email | 
*----*-------*

我想选择在events表中至少有两个活动在不同日期发生的所有用户。此外,其中一项活动需要在过去7天内完成。

这是我到目前为止所做的:

SELECT x.`email` 
  FROM (
      SELECT u.`email`, CAST(e.`occurred_on` AS DATE) d
        FROM `users` u
        JOIN `event_stream` e
             ON e.`user_id` = u.`id`
    GROUP BY CAST(e.`occurred_on` AS DATE), u.`email`
  ) x
GROUP BY x.`email`
  HAVING COUNT(*) > 1

这应该给我所有在至少两天内登录活动的用户。现在我不太确定如何添加我对这些活动的其他限制,其中一个必须在过去7天内发生。

2 个答案:

答案 0 :(得分:2)

按用户分组并有条件地计数:

select * 
from users
where id in
(
  select user_id
  from event_stream
  group by user_id
  having count(distinct date(occurred_on)) > 1 -- at least on two different days
     and sum(occurred_on >= current_date - interval 7 day) > 0 -- one in last seven days
);

在MySQL中,true = 1,false = 0,因此我们可以对布尔表达式求和,以计算它匹配的频率。

如果occurred_on已经是名称所暗示的日期,而不是日期时间或时间戳,则可以将count(distinct date(occurred_on))更改为count(distinct occurred_on)

答案 1 :(得分:1)

having中再添加一个条件。

SELECT x.`email` 
  FROM (
      SELECT u.`email`, CAST(e.`occurred_on` AS DATE) d
        FROM `users` u
        JOIN `event_stream` e
             ON e.`user_id` = u.`id`
    GROUP BY CAST(e.`occurred_on` AS DATE), u.`email`
  ) x
GROUP BY x.`email`
HAVING COUNT(*) > 1 AND SUM(DATEDIFF(now(),d)>=0 AND DATEDIFF(now(),d)<=7) > 0

DATEDIFF(now(),d)>=0 AND DATEDIFF(now(),d)<=7的计算结果为1或0,具体取决于条件是真还是假。