求每个PRODUCT的去重USER_ID数及按TYPE分组的去重USER_ID数(SQL)
用窗口函数实现产品维度的去重用户统计(含全局与分类)
需求说明
现有表包含USER_ID、TYPE、PRODUCT三列,存在重复行。需完成以下统计:
- 每个
PRODUCT对应的去重USER_ID总数 - 每个
PRODUCT下各TYPE对应的去重USER_ID数
要求仅使用窗口函数,禁止使用JOIN/UNION操作。
示例输入
| USER_ID | TYPE | PRODUCT |
|---|---|---|
| 11111 | Adidas | Shirt |
| 11111 | Adidas | Shirt |
| 11111 | Nike | Shirt |
| 22222 | Nike | Shirt |
| 11111 | Adidas | Short |
| 22222 | Nike | Short |
| 22222 | Puma | Short |
期望输出
| PRODUCT | TYPE | COUNT |
|---|---|---|
| Shirt | - | 2 |
| Shirt | Adidas | 1 |
| Shirt | Nike | 2 |
| Short | - | 2 |
| Short | Adidas | 1 |
| Short | Nike | 1 |
| Short | Puma | 1 |
解决方案
SELECT DISTINCT PRODUCT, CASE WHEN rn = 1 THEN '-' ELSE TYPE END AS TYPE, CASE WHEN rn = 1 THEN product_user_count ELSE type_user_count END AS COUNT FROM ( SELECT PRODUCT, TYPE, COUNT(DISTINCT USER_ID) OVER (PARTITION BY PRODUCT) AS product_user_count, COUNT(DISTINCT USER_ID) OVER (PARTITION BY PRODUCT, TYPE) AS type_user_count, ROW_NUMBER() OVER (PARTITION BY PRODUCT ORDER BY TYPE) AS rn FROM your_table_name ) t ORDER BY PRODUCT, TYPE;
思路解析
- 内层子查询:
- 用
COUNT(DISTINCT USER_ID) OVER (PARTITION BY PRODUCT)计算每个产品的去重用户总数,存入product_user_count - 用
COUNT(DISTINCT USER_ID) OVER (PARTITION BY PRODUCT, TYPE)计算每个产品下各类型的去重用户数,存入type_user_count - 用
ROW_NUMBER() OVER (PARTITION BY PRODUCT ORDER BY TYPE)给每个产品下的记录排序,标记出每个产品的第一条记录(rn=1)
- 用
- 外层查询:
- 通过
DISTINCT去除原表重复行带来的重复统计结果 - 用
CASE语句将每个产品的第一条记录的TYPE替换为-,并使用全局统计值product_user_count,其余行保留原TYPE和分类统计值type_user_count - 最后按
PRODUCT和TYPE排序,匹配期望输出的顺序
- 通过
内容的提问来源于stack exchange,提问作者Sweet
相关产品推荐
相关产品推荐

