2021-09-26 10:39:18
SQL中结果集排序的两种经典方法为ORDER BY子句和窗口函数,具体说明如下:
一、使用ORDER BY子句排序ORDER BY是SQL中最基础且常用的排序方法,允许通过指定一个或多个列对结果集进行全局排序。
基本语法
SELECT 列名 FROM 表名 ORDER BY 列名 [ASC|DESC], 列名 [ASC|DESC], ...;默认按升序(ASC)排列,可显式指定降序(DESC)。
多列排序时,列顺序决定优先级,先按第一列排序,再按后续列细化排序。
示例
单列排序:按工资降序排列员工信息。SELECT id, name, salary FROM employees ORDER BY salary DESC;
多列排序:先按部门升序,再按工资降序排列。SELECT id, name, department, salary FROM employees ORDER BY department ASC, salary DESC;
NULL值处理不同数据库对NULL值的默认排序行为不同(可能排在最前或最后)。可通过NULLS FIRST或NULLS LAST显式控制位置(如PostgreSQL支持此语法)。示例:将工资为NULL的员工排在最后。
SELECT id, name, salary FROM employees ORDER BY salary DESC NULLS LAST;窗口函数(如RANK()、DENSE_RANK()、ROW_NUMBER())可在结果集的分区内实现复杂排序,适用于分组内排名或分页等场景。
核心语法
函数名() OVER (PARTITION BY 分组列 ORDER BY 排序列 [ASC|DESC])PARTITION BY:将数据划分为多个分组。
ORDER BY:定义组内排序方式。
常用窗口函数
RANK():分配排名,相同值排名相同,后续排名跳过(如1,2,2,4)。
DENSE_RANK():分配排名,相同值排名相同,后续排名连续(如1,2,2,3)。
ROW_NUMBER():为每行分配唯一序号,即使值相同(如1,2,3,4)。
示例
计算每个部门内员工的工资排名:SELECT id, name, department, salary, RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rank_within_deptFROM employees;
生成每月销售额前5的产品报表(结合CTE优化):WITH RankedSales AS ( SELECT product_id, month, total_sales, RANK() OVER (PARTITION BY month ORDER BY total_sales DESC) AS sales_rank FROM sales_data)SELECT product_id, month, total_salesFROM RankedSalesWHERE sales_rank <= 5;
ORDER BY子句
优势:简单全局排序时性能更优,可直接利用索引。
局限:无法直接实现分组内排序或复杂排名逻辑。
窗口函数
优势:支持分区内排序和排名,避免多次查询或临时表,适合复杂分析场景。
局限:语法较复杂,性能可能受数据量影响。
选择建议
简单全局排序用ORDER BY。
分组内排名或分页用窗口函数。
实际性能需通过测试验证,因数据库实现和数据量而异。


通过灵活运用ORDER BY和窗口函数,可高效满足从简单排序到复杂分析的多样化需求。