SQL示例:为什么同样的条件需要重复两次排序

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

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 缺一不可,第一个影响排名逻辑,第二个影响最终输出顺序。

相关推荐
常常有10 小时前
MySQL 底层执行原理:输入SQL语句到两阶段提交
数据库·sql·mysql
海市公约12 小时前
一条SQL查询的完整旅程:MySQL执行流程深度解析
sql·mysql·数据库优化·执行计划·连接器·查询缓存·sql执行原理
这个DBA有点耶13 小时前
COUNT进阶:超大表的近似计数与HyperLogLog
数据库·sql·程序人生·学习方法·dba·改行学it
淘矿人17 小时前
【AI大模型】AI 大模型推理平台完整测评:8 家主流聚合服务对比分析
人工智能·sql·gpt·学习·github·php
宋浮檀s19 小时前
SQL注入基础+DVWA搭建
数据库·sql·安全·网络安全
Amarantine、沐风倩✨19 小时前
Oracle 性能排查:通过 V$LONG_EXEC_SQLS 快速定位慢 SQL
数据库·sql·oracle
倔强的石头10619 小时前
生产环境排坑实录:SQL 标量子查询的“静默杀手”与优化器的智能推演
数据库·sql
老码观察20 小时前
MySQL 慢 SQL 治理实战:从索引原理到真实踩坑
sql·mysql
不太厉害的程序员21 小时前
Oracle使用工具PL/SQL Developer中的数据泵备份还原数据库
数据库·sql·oracle
三十六煩惱風21 小时前
2026-05/04~10技术问题处理
java·数据库·sql