如何在MySQL中筛选近14天及未来无指定事件的用户?
正确查询语句及原问题分析
首先明确需求核心:找出所有用户,这些用户在2022-08-19(当前日期2022-09-01往前推14天)至未来的所有时间段里,从未产生过event_name匹配%cbt care%的事件。
原查询的问题
原语句逻辑完全和需求相反:它是在筛选存在%cbt care%事件且发生在14天前的记录,既没有判断用户在整个目标时间段内“完全无该事件”,也没有覆盖未来时间段,自然会错误包含像user_id=x这种在未来(2022-09-10)有该事件的用户。
两种正确写法
方法1:使用NOT EXISTS子查询
逻辑直观,先排除掉所有在目标时间段内有%cbt care%事件的用户:
SELECT DISTINCT user_id FROM test_table t_main WHERE NOT EXISTS ( SELECT 1 FROM test_table t_sub WHERE t_sub.user_id = t_main.user_id AND t_sub.event_name LIKE '%cbt care%' AND t_sub.start_date >= DATE_SUB('2022-09-01', INTERVAL 14 DAY) );
- 用
DISTINCT确保每个用户只返回一次 - 子查询负责找出所有在2022-08-19及之后有
%cbt care%事件的用户,主查询取不在这个范围内的用户
方法2:使用GROUP BY + HAVING聚合判断
通过分组统计每个用户的符合条件事件数量,筛选出数量为0的用户:
SELECT user_id FROM test_table GROUP BY user_id HAVING SUM( CASE WHEN event_name LIKE '%cbt care%' AND start_date >= DATE_SUB('2022-09-01', INTERVAL 14 DAY) THEN 1 ELSE 0 END ) = 0;
- 分组后用
CASE语句标记符合条件的事件,SUM统计每个用户的这类事件总数 HAVING SUM(...) = 0表示该用户在目标时间段内完全没有%cbt care%事件
如果需要获取用户的其他完整信息,可以调整为:
SELECT DISTINCT t.* FROM test_table t WHERE NOT EXISTS ( SELECT 1 FROM test_table t_sub WHERE t_sub.user_id = t.user_id AND t_sub.event_name LIKE '%cbt care%' AND t_sub.start_date >= DATE_SUB('2022-09-01', INTERVAL 14 DAY) );
内容的提问来源于stack exchange,提问作者CommonSenseCode
相关产品推荐
相关产品推荐

