在 Oracle 数据库中,想要查询员工表(EMPLOYEES)中工资(SALARY)高于平均工资的员工信息,以下正确的 SQL 语句是
A
SELECT * FROM EMPLOYEES HAVING SALARY > (SELECT AVG(SALARY) FROM EMPLOYEES);
B
SELECT * FROM EMPLOYEES, (SELECT AVG(SALARY) FROM EMPLOYEES) AS AVG_SALARY WHERE SALARY > AVG_SALARY;
C
SELECT * FROM EMPLOYEES WHERE SALARY > (SELECT AVG(SALARY) FROM EMPLOYEES);
D
SELECT * FROM EMPLOYEES WHERE SALARY > AVG(SALARY);
正确答案:C(SELECT * FROM EMPLOYEES WHERE SALARY > (SELECT AVG(SALARY) FROM EMPLOYEES);)
核心逻辑解析
子查询的正确使用:
该语句通过子查询(SELECT AVG(SALARY) FROM EMPLOYEES)计算所有员工的平均工资,并将其作为过滤条件直接嵌入WHERE子句。这是单行子查询的典型用法,返回一个单值(平均工资),外层查询通过WHERE SALARY >进行逐行比对。无需分组或别名:
由于子查询返回的是全表的平均工资,无需对结果进行分组(GROUP BY)或额外定义别名(如AS AVG_SALARY),语法简洁且符合Oracle规范。
示例参考
网页3中明确给出相同结构的查询示例:
SELECT * FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
该写法与选项C完全一致,验证了其正确性。
其他选项错误原因分析
A(使用HAVING子句)
• 错误点:HAVING子句用于对分组后的结果进行过滤,必须与GROUP BY配合使用。而此查询未分组,直接使用HAVING会导致语法错误。
• 修正方法:若强行使用HAVING,需先分组,但逻辑不适用(如GROUP BY 1强行分组),反而增加复杂度。
B(子查询作为内联视图未定义别名)
• 错误点:子查询(SELECT AVG(SALARY) FROM EMPLOYEES)作为内联视图时,未正确指定别名(如AS AVG_SALARY),且未提取子查询结果字段。正确写法应为:
SELECT e.*
FROM EMPLOYEES e, (SELECT AVG(SALARY) avg_sal FROM EMPLOYEES) avg_tab
WHERE e.SALARY > avg_tab.avg_sal;
原选项缺少别名和字段引用,无法执行。
D(直接使用AVG未嵌套子查询)
• 错误点:AVG(SALARY)是聚合函数,不能在WHERE子句中直接使用。Oracle要求聚合函数必须通过子查询或GROUP BY分组后使用。
• 修正方法:必须将聚合函数包裹在子查询中,如选项C的写法。
总结与最佳实践
| 选项 | 正确性 | 关键问题 | 参考文档 |
|---|---|---|---|
| A | ❌ | HAVING未与GROUP BY配合 | |
| B | ❌ | 未定义别名及字段引用 | |
| C | ✅ | 单行子查询直接嵌入WHERE | |
| D | ❌ | 聚合函数未通过子查询或分组 |
实际建议:
• 优先使用选项C:简洁高效,符合Oracle对子查询的标准处理逻辑。
• 避免复杂写法:如无必要,不要将子查询拆分为内联视图或强制分组。
• 性能优化:若表数据量较大,可为SALARY字段添加索引,或定期收集统计信息以优化子查询效率。




