Oracle SQL:如何从三表关联生成用户状态统计的多行结果
解决Oracle用户状态统计问题
原SQL的问题
- 语法错误:
(DISTINCT RequestSatusTable.StatusId)写法违规,DISTINCT不能单独包裹单个字段,若需去重应放在SELECT开头,但此处场景无需去重。 - 分组逻辑缺失:仅按
PersonTable.Person分组,无法区分同一用户的不同状态,导致无法得到各状态的单独计数。 - 拼写错误:
PersonTable.Perosn应为PersonTable.Person。
正确SQL语句
SELECT pt.Person AS person, CASE rst.StatusID WHEN 1 THEN 'good' WHEN 0 THEN 'bad' ELSE 'unknown' -- 处理未定义的状态值 END AS status, COUNT(rst.StatusID) AS status_count FROM PersonTable pt JOIN TypeToPersonTable ttp ON pt.ID = ttp.PersonID JOIN RequestSatusTable rst ON rst.SPECID = ttp.SPECID GROUP BY pt.Person, rst.StatusID ORDER BY pt.Person, rst.StatusID;
关键说明
- 状态映射:用
CASE表达式将数字状态ID转换为指定文本,同时预留ELSE分支处理异常状态值。 - 分组逻辑:同时按用户和状态ID分组,确保每个用户的每种状态能单独统计计数。
- 表别名:使用短别名简化SQL结构,提升可读性。
- 排序优化:添加
ORDER BY让结果按用户、状态有序展示,更直观。
如果需要统计无状态记录的用户(即即使没有关联状态也要显示),可改用左连接:
SELECT pt.Person AS person, CASE COALESCE(rst.StatusID, -1) WHEN 1 THEN 'good' WHEN 0 THEN 'bad' ELSE 'no_status' END AS status, COUNT(rst.StatusID) AS status_count FROM PersonTable pt LEFT JOIN TypeToPersonTable ttp ON pt.ID = ttp.PersonID LEFT JOIN RequestSatusTable rst ON rst.SPECID = ttp.SPECID GROUP BY pt.Person, COALESCE(rst.StatusID, -1) ORDER BY pt.Person;
内容的提问来源于stack exchange,提问作者slade
相关产品推荐
相关产品推荐

