1. 概述
在日常的工作中,我们经常会遇到需要对数据进行排序的情况,如统计销售额排名前十的产品、筛选最新的记录等,而SQL Server提供了强大的排序功能,通过合理运用,可以大大提高数据的分析和处理效率。
2. 基本排序技巧
2.1 ORDER BY
ORDER BY
是排序最基本的语法,它可以根据指定的列对结果集进行升序或降序排序,默认情况下为升序排序。它的语法如下:
SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;
示例1:查询学生表中的所有记录,并按照成绩降序排列,若成绩相同则按照姓名升序排列。
SELECT *
FROM student
ORDER BY grade DESC, name ASC;
2.2 TOP
TOP
可以用来限制结果集返回的行数,结合ORDER BY
可以获取TopN的记录。它的语法如下:
SELECT TOP N column1, column2, ...
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;
示例2:查询学生表中成绩前五的学生信息。
SELECT TOP 5 *
FROM student
ORDER BY grade DESC;
2.3 DISTINCT
DISTINCT
可以去除结果集中重复的记录,结合其它排序语法可以达到筛选最新的记录等效果。它的语法如下:
SELECT DISTINCT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;
示例3:查询订单表中最新的日期。
SELECT TOP 1 DISTINCT date
FROM order
ORDER BY date DESC;
3. 高级排序技巧
3.1 排名函数
排名函数可以用来给结果集中每一行分配一个排名值,包括RANK()
、DENSE_RANK()
、ROW_NUMBER()
等函数。
3.1.1 RANK()
RANK()
函数返回结果集中每一行的排名,如果有相同的值,则排名相同,有相同的值后面的行跳过相同的行,继续排名它的语法如下:
SELECT column1, column2, ..., RANK() OVER (ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...) As rank
FROM table_name;
示例4:查询学生表中每个班级成绩排名前三的学生。
SELECT name, grade, class, RANK() OVER (PARTITION BY class ORDER BY grade DESC) AS rank
FROM student
WHERE rank <= 3;
3.1.2 DENSE_RANK()
DENSE_RANK()
函数返回结果集中每一行的排名,如果有相同的值,则排名相同,有相同的值后面的行不跳过相同的行,继续排名它的语法如下:
SELECT column1, column2, ..., DENSE_RANK() OVER (ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...) As rank
FROM table_name;
示例5:查询销售表中前五名的商品及数量。
SELECT TOP 5 product, SUM(quantity) AS total_quantity, DENSE_RANK() OVER (ORDER BY SUM(quantity) DESC) AS rank
FROM sales
GROUP BY product
ORDER BY total_quantity DESC;
3.1.3 ROW_NUMBER()
ROW_NUMBER()
函数为结果集中的每一行都分配唯一的行号,行号从1开始递增。它的语法如下:
SELECT column1, column2, ..., ROW_NUMBER() OVER (ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...) As row_number
FROM table_name;
示例6:查询员工表中所有员工的基本信息,并按照薪水降序排序,同时展示每一行的行号。
SELECT *, ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_number
FROM employee;
3.2 联结排序
在有些情况下,我们需要对多张表进行联结,然后根据联结后的结果排序,可以通过子查询或公用表表达式等方式实现。
3.2.1 子查询排序
子查询排序先使用子查询获取排序后的结果集,再联结到主查询中。它的语法如下:
SELECT column1, column2, ...
FROM table1
JOIN (SELECT column1, column2, ...
FROM table2
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...) AS sub_query
ON table1.key = sub_query.key
ORDER BY sub_query.column1 [ASC | DESC], sub_query.column2 [ASC | DESC], ...;
示例7:查询订单表中最新日期的订单及其商品信息。
SELECT order.id, product, quantity, order.date
FROM order
JOIN (SELECT TOP 1 id, date
FROM order
ORDER BY date DESC) AS sub_query
ON order.id = sub_query.id;
3.2.2 公用表表达式排序
公用表表达式排序先使用公用表表达式获取排序后的结果集,再联结到主查询中。它的语法如下:
WITH sub_query AS (
SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...
)
SELECT column1, column2, ...
FROM table1
JOIN sub_query
ON table1.key = sub_query.key
ORDER BY sub_query.column1 [ASC | DESC], sub_query.column2 [ASC | DESC], ...;
示例8:查询学生表中成绩排名前五的学生所在的年级列表。
WITH sub_query AS (
SELECT name, grade, ROW_NUMBER() OVER (PARTITION BY grade ORDER BY grade DESC) AS rank
FROM student
WHERE rank <= 5
)
SELECT DISTINCT grade
FROM student
WHERE EXISTS (SELECT 1 FROM sub_query WHERE student.grade = sub_query.grade);
4. 结语
本文介绍了SQL Server常用的排序技巧,包括基本排序技巧和高级排序技巧,其中高级排序技巧涉及到排名函数、联结排序等内容,这些技巧可以大大提高数据的分析和处理效率,为数据挖掘和统计分析提供了有力的支持。