SQL查询中两个ORDER BY子句作用不同,不是冗余。
第一个在窗口函数内(DENSE_RANK() OVER(ORDER BY salary DESC))决定排名规则;第二个在语句末尾(ORDER BY salary DESC,emp_no)控制结果输出顺序。
示例显示:若不使用第二个ORDER BY,相同工资的员工可能不按emp_no升序排列。
两个ORDER BY分别服务于排名计算和结果排序两个不同阶段,确保既正确计算排名又满足最终显示顺序要求。
SQL示例:为什么同样的条件需要重复两次排序
题目描述
有一个薪水表salaries简况如下:
| emp_no | salary | from_date | to_date |
| 10001 | 88958 | 2002-06-22 | 9999-01-01 |
| 10002 | 72527 | 2001-08-02 | 9999-01-01 |
| 10003 | 43311 | 2001-12-01 | 9999-01-01 |
| 10004 | 72527 | 2001-12-01 | 9999-01-01 |
对所有员工的薪水按照salary降序先进行1-N的排名,如果salary相同,再按照emp_no升序排列:
| emp_no | salary | t_rank |
| 10001 | 88958 | 1 |
| 10002 | 72527 | 2 |
| 10004 | 72527 | 2 |
| 10003 | 43311 | 3 |
这个 SQL 中的两个ORDER BY其实目的不同,不是冗余,而是分别服务于两个不同的阶段:
1. 你写的 SQL
sql
SELECT emp_no, salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS t_rank FROM salaries ORDER BY salary DESC, emp_no;第一个
ORDER BY(在窗口函数内)DENSE_RANK() OVER (ORDER BY salary DESC)
决定排名规则—— 按工资降序排名。第二个
ORDER BY(在语句末尾)ORDER BY salary DESC, emp_no
决定结果集的输出顺序。
2. 为什么需要两次?
题目要求:
对所有员工的薪水按照 salary 降序先进行 1-N 的排名,如果 salary 相同,再按照 emp_no 升序排列。
这个 “再按照 emp_no 升序排列” 指的是输出结果的顺序,而不是排名规则。
最终结果需要:
按工资从高到低排序
工资相同的员工,按
emp_no升序
如果不写最后的ORDER BY salary DESC, emp_no
结果集会按窗口函数的分区/排序顺序输出,但在某些数据库中可能是不确定的顺序(比如按物理存储顺序)。
对于工资相同的员工(例如 72527),可能输出顺序是10004在前、10002在后,不符合“emp_no 升序”的要求。
3. 示例验证
数据:
text
10001 88958 10002 72527 10004 72527 10003 43311
窗口函数
DENSE_RANK()已经正确计算排名:88958 → 1
72527 → 2
43311 → 3
如果没有最后
ORDER BY salary DESC, emp_no:
可能输出:text
10001 88958 1 10004 72527 2 ← emp_no 大的反而在前 10002 72527 2 10003 43311 3
加上最后的
ORDER BY salary DESC, emp_no:text
10001 88958 1 10002 72527 2 ← emp_no 小的在前 10004 72527 2 10003 43311 3
4. 总结
| 位置 | 作用 |
|---|---|
OVER (ORDER BY salary DESC) | 决定排名的数值(1,2,3...) |
末尾ORDER BY salary DESC, emp_no | 决定最终结果集的显示顺序(满足“同薪按 emp_no 升序”) |
两个ORDER BY缺一不可,第一个影响排名逻辑,第二个影响最终输出顺序。