如何用SQL高效检查用户是否存在指定事件?
解决方案
方法一:分组+条件聚合(推荐)
这是最简洁易维护的写法,无需UNION,直接按User分组后判断该用户是否存在Event='c'的记录:
SELECT User, CASE WHEN MAX(CASE WHEN Event = 'c' THEN 1 ELSE 0 END) = 1 THEN 'y' ELSE 'n' END AS is_occured FROM EVENTS GROUP BY User;
也可以用更直观的子查询版本(主流数据库如MySQL、PostgreSQL均支持):
SELECT DISTINCT User, CASE WHEN EXISTS (SELECT 1 FROM EVENTS e2 WHERE e2.User = EVENTS.User AND e2.Event = 'c') THEN 'y' ELSE 'n' END AS is_occured FROM EVENTS;
这类写法的优势很明显:后续表新增字段时,核心判断逻辑无需修改,只需要关注User和目标Event的关联,维护成本极低。
关于窗口函数的思路
窗口函数确实能实现需求,但并非最优选择——因为我们只需要按用户分组的聚合结果,窗口函数更多用于保留原表行结构的同时计算分组统计值。如果一定要用窗口函数,写法如下:
SELECT DISTINCT User, CASE WHEN MAX(CASE WHEN Event = 'c' THEN 1 ELSE 0 END) OVER (PARTITION BY User) = 1 THEN 'y' ELSE 'n' END AS is_occured FROM EVENTS;
逻辑和分组聚合一致,但需要额外去重,效率不如直接GROUP BY。
原UNION写法的问题
原写法需要分别筛选有/无目标事件的用户,不仅容易出现逻辑漏洞(比如用户同时存在目标事件和其他事件时,会产生重复行),而且后续表新增字段时,两个UNION分支都要同步修改,维护性很差。
内容的提问来源于stack exchange,提问作者thejoker34
相关产品推荐
相关产品推荐

