按分类条件分组记录:用户权限统计SQL问题排查
问题原因及解决方法
你的问题核心是两个点:要么是GROUP BY子句里多包含了permission字段,要么是CASE语句没有和聚合函数配合使用,这两种情况都会导致每个权限状态单独占一行,而不是合并成同一user_id的一行结果。
错误写法示例(导致分多行的常见情况)
比如你可能写了类似这样的SQL:
SELECT user_id, permission, CASE WHEN permission = 'Denied' THEN 1 ELSE 0 END AS denied_count, CASE WHEN permission = 'Limited' THEN 1 ELSE 0 END AS limited_count, CASE WHEN permission = 'Permitted' THEN 1 ELSE 0 END AS permitted_count FROM your_table GROUP BY user_id, permission;
这里因为GROUP BY同时包含了user_id和permission,所以会按每个用户+每个权限状态分组,自然每个状态单独一行。
正确写法(合并为一行)
要把同一user_id的三个状态计数合并到一行,需要用聚合函数(比如COUNT或SUM)包裹CASE语句,并且GROUP BY只保留user_id:
SELECT user_id, COUNT(CASE WHEN permission = 'Denied' THEN 1 END) AS denied_count, COUNT(CASE WHEN permission = 'Limited' THEN 1 END) AS limited_count, COUNT(CASE WHEN permission = 'Permitted' THEN 1 END) AS permitted_count FROM your_table GROUP BY user_id;
或者用SUM也可以,效果一样:
SELECT user_id, SUM(CASE WHEN permission = 'Denied' THEN 1 ELSE 0 END) AS denied_count, SUM(CASE WHEN permission = 'Limited' THEN 1 ELSE 0 END) AS limited_count, SUM(CASE WHEN permission = 'Permitted' THEN 1 ELSE 0 END) AS permitted_count FROM your_table GROUP BY user_id;
原理说明
- 聚合函数(COUNT/SUM)会对
GROUP BY user_id分组后的所有行进行汇总计算。 - CASE语句会判断当前行的permission是否符合条件,符合就返回1(COUNT会统计非NULL值,所以也可以不写ELSE,默认返回NULL不会被计数),不符合就返回0或NULL。
- 最终每个用户的三个状态计数会被聚合到同一行里。
内容的提问来源于stack exchange,提问作者Avan Maric
相关产品推荐
相关产品推荐

