SQL查询:筛选'Did X'发生时间晚于'Did Y'的用户ID
需求说明
- 待查询的用户行为表包含3个核心字段:用户ID(
user_id)、事件类型(event,枚举值含logged in、did X、did Y等)、事件时间戳(event_ts),单个用户可对应多条行为记录 - 查询目标:返回所有满足「
Did X事件发生时间晚于Did Y事件发生时间」的用户ID
判定规则
- 同一用户多次触发同类事件时,仅对比两类事件的最新发生时间:即用户最新一次
Did X的时间戳 > 最新一次Did Y的时间戳,即符合返回要求 - 从未触发过
Did Y事件,但至少触发过一次Did X的用户,属于符合要求的返回范围 - 从未触发过
Did X事件的用户直接排除
实现方案
不需要写复杂的多表自连接,用条件聚合的写法即可,逻辑简洁且执行效率高,适配所有支持标准SQL的数据库:
SELECT user_id FROM 用户行为表名 -- 替换为实际表名 WHERE event IN ('Did X', 'Did Y') GROUP BY user_id HAVING -- 校验用户至少触发过一次Did X MAX(CASE WHEN event = 'Did X' THEN event_ts END) IS NOT NULL AND ( -- 未触发过Did Y的用户直接符合要求 MAX(CASE WHEN event = 'Did Y' THEN event_ts END) IS NULL -- 触发过两类事件的用户,对比最新时间戳 OR MAX(CASE WHEN event = 'Did X' THEN event_ts END) > MAX(CASE WHEN event = 'Did Y' THEN event_ts END) )
写法说明:
- 先通过WHERE条件过滤掉和两类目标事件无关的记录,减少分组计算的数据量
- 按用户ID分组后,用CASE搭配MAX函数,直接提取每个用户两类事件的最新时间戳:如果用户从未触发过某类事件,对应计算结果为NULL
- 所有判定逻辑直接在HAVING子句中完成,不需要嵌套多层子查询,也不需要做自连接关联,单次表扫描即可返回结果
内容的提问来源于stack exchange,提问作者GlassRat
相关产品推荐
相关产品推荐

