SQL需求:统计各模块A、B事件的独立发生天数
解决方案:统计模块A/B事件的独立天数
嘿,我明白你为啥卡壳了——直接用GROUP BY加COUNT会把同一天内的多次重复事件算进去,而我们要的是独立天数,核心是先按「模块+日期」维度聚合,判断当天是否发生过A/B事件,再统计符合条件的天数。下面给你两种可行的SQL方案:
方案1:条件聚合直接统计
这种方法用CASE WHEN搭配COUNT(DISTINCT)一步到位,逻辑清晰:
SELECT Module, -- 统计有A事件的独立天数:仅保留A事件的日期,去重后计数 COUNT(DISTINCT CASE WHEN Occurrence = 'A' THEN DATE(Timestamp) END) AS Occurence_A, -- 同理统计B事件的独立天数 COUNT(DISTINCT CASE WHEN Occurrence = 'B' THEN DATE(Timestamp) END) AS Occurence_B FROM your_test_table -- 替换成你的表名 GROUP BY Module;
逻辑解释:
DATE(Timestamp)把时间戳截断为日期,提取出事件发生的当天CASE WHEN会筛选出对应事件的日期,非目标事件的行返回NULLCOUNT(DISTINCT ...)会自动忽略NULL,只统计不重复的日期数量,也就是该模块至少发生一次目标事件的独立天数
方案2:先聚合每日事件再统计
如果觉得第一种方法不够直观,可以先用CTE(公共表表达式)先算出每个模块每天是否发生过A/B事件,再汇总天数:
WITH daily_module_events AS ( SELECT Module, DATE(Timestamp) AS event_date, -- 当天只要有一次A事件,就标记为1,否则0 MAX(CASE WHEN Occurrence = 'A' THEN 1 ELSE 0 END) AS has_A, -- 同理标记当天是否有B事件 MAX(CASE WHEN Occurrence = 'B' THEN 1 ELSE 0 END) AS has_B FROM your_test_table -- 替换成你的表名 GROUP BY Module, DATE(Timestamp) ) SELECT Module, SUM(has_A) AS Occurence_A, -- 求和得到有A事件的总天数 SUM(has_B) AS Occurence_B -- 求和得到有B事件的总天数 FROM daily_module_events GROUP BY Module;
逻辑解释:
- 内层CTE先按「模块+日期」分组,用
MAX判断当天是否发生过目标事件(只要有一次,MAX结果就是1) - 外层对
has_A和has_B求和,本质就是统计有多少天发生过对应事件
验证结果
这两种方案都会输出你预期的结果:
| Module | Occurence_A | Occurence_B |
|---|---|---|
| M1 | 3 | 1 |
| M2 | 2 | 3 |
内容的提问来源于stack exchange,提问作者JorDik
相关产品推荐
相关产品推荐

