基于EMP、DEPT表统计各位置部门数与员工数的SQL编写及报错排查
报错原因定位
- 触发
missing expression的核心原因:这套EMP/DEPT表是Oracle示例库的经典表结构,其语法规则要求COUNT()聚合函数仅支持合法的列、常量、运算表达式作为入参,不允许直接将返回多行结果的子查询写在COUNT()的括号范围内。解析器遇到这种结构时,无法将子查询识别为COUNT的有效统计对象,会直接判定为语法缺失。 - 写法的逻辑错位:你原本想通过相关子查询统计各位置员工总数的思路是合理的,但错误地将整段子查询嵌套在了
COUNT()内部。即便调整语法通过运行,子查询中重复关联DEPT表的写法也会带来不必要的性能开销,且如果某个位置下没有员工,子查询返回空值时统计结果也容易出现偏差。
正确实现方案
核心统计逻辑
两种经过验证的写法均可满足需求,可根据数据量选择:
- 一次连接统计法(适合小数据量表,代码简洁)
直接关联DEPT和EMP表后按位置分组,统计部门数时必须对DEPTNO去重,避免因为单部门下存在多名员工,导致连接后部门数被重复计数。使用左连接可以保证没有员工的部门所属位置也被完整列出,不会因为未关联到员工就丢失该位置的统计信息:SELECT D.LOC AS Loc, COUNT(DISTINCT D.DEPTNO) AS loc_dept_total, COUNT(E.EMPNO) AS loc_emp_total FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO GROUP BY D.LOC; - 分步聚合统计法(适合大数据量表,性能更优)
先分别聚合每个位置的部门数、每个位置的员工数,再将两个结果集按位置关联,避免连接后数据膨胀带来的统计误差:WITH dept_agg AS ( SELECT LOC, COUNT(DEPTNO) AS dept_cnt FROM DEPT GROUP BY LOC ), emp_agg AS ( SELECT D.LOC, COUNT(E.EMPNO) AS emp_cnt FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO GROUP BY D.LOC ) SELECT da.LOC AS Loc, da.dept_cnt AS loc_dept_total, ea.emp_cnt AS loc_emp_total FROM dept_agg da LEFT JOIN emp_agg ea ON da.LOC = ea.LOC;
视图创建
将上述统计逻辑包裹在视图定义中,即可生成符合需求的持久化查询对象,以一次连接统计法为例:
CREATE OR REPLACE VIEW v_loc_stat AS SELECT D.LOC AS Loc, COUNT(DISTINCT D.DEPTNO) AS loc_dept_total, COUNT(E.EMPNO) AS loc_emp_total FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO GROUP BY D.LOC;
内容的提问来源于stack exchange,提问作者Alessio Giovannini
相关产品推荐
相关产品推荐

