如何用Partition By实现单列双值的SQL数据统计与透视表生成
按多字段分组统计不同event_name行数的解决方案
原始数据表
| stream_id | event_date | event_name | promo_name | slot |
|---|---|---|---|---|
| 123 | 01012222 | select | banana | A1 |
| 123 | 01012222 | select | banana | A2 |
| 123 | 01012222 | select | banana | A3 |
| 123 | 01012222 | select | banana | A3 |
| 123 | 01012222 | select | banana | A3 |
| 123 | 01012222 | view | banana | A1 |
| 123 | 01012222 | view | banana | A1 |
| 123 | 01012222 | view | banana | A2 |
| 123 | 01012222 | view | banana | A3 |
| 123 | 01012222 | view | banana | A4 |
目标透视表
| stream_id | event_date | promo_name | slot | event_name_select_count | event_name_view_count |
|---|---|---|---|---|---|
| 123 | 01012222 | banana | A1 | 1 | 2 |
| 123 | 01012222 | banana | A2 | 1 | 1 |
| 123 | 01012222 | banana | A3 | 3 | 1 |
| 123 | 01012222 | banana | A4 | 0 | 1 |
尝试过的SQL
SELECT stream_id, event_date, event_name, promo_name, slot, COUNT(event_name) OVER (PARTITION BY stream_id,event_date, promo_name, slot) AS event_name_count FROM `TABLE`
可行SQL方案
方案一:条件聚合(推荐)
直接使用GROUP BY结合CASE WHEN实现条件统计,逻辑清晰且高效:
SELECT stream_id, event_date, promo_name, slot, COUNT(CASE WHEN event_name = 'select' THEN 1 END) AS event_name_select_count, COUNT(CASE WHEN event_name = 'view' THEN 1 END) AS event_name_view_count FROM `TABLE` GROUP BY stream_id, event_date, promo_name, slot ORDER BY slot;
CASE WHEN会针对每行判断event_name值,符合条件返回1,否则返回NULL;COUNT函数自动忽略NULL,从而得到对应event_name的行数- 分组字段确保每个结果行对应唯一的
stream_id+event_date+promo_name+slot组合 - 无对应event_name的分组会自动返回0,满足需求
方案二:窗口函数+去重
如果偏好窗口函数写法,可通过窗口函数统计后去重:
SELECT DISTINCT stream_id, event_date, promo_name, slot, COUNT(CASE WHEN event_name = 'select' THEN 1 END) OVER (PARTITION BY stream_id, event_date, promo_name, slot) AS event_name_select_count, COUNT(CASE WHEN event_name = 'view' THEN 1 END) OVER (PARTITION BY stream_id, event_date, promo_name, slot) AS event_name_view_count FROM `TABLE` ORDER BY slot;
窗口函数对每个分组计算统计值,再通过DISTINCT去除重复行,最终得到目标结果。
内容的提问来源于stack exchange,提问作者tarik
相关产品推荐
相关产品推荐

