CodeGym /课程 /SQL SELF /多列排序:排序顺序和优先级

多列排序:排序顺序和优先级

SQL SELF
第 6 级 , 课程 2
可用

想象一下,你在搞一个超大的学生数据库。只按姓排序已经挺有用了,但你想想,如果表里有好几个学生同姓,那你看起来就有点乱。这时候,为了让结果更清晰,你可以再加个名字排序。再比如,你想先按订单日期排,再按订单总额排。这种时候,多列排序就派上用场了

多列排序能让你:1. 按你想要的顺序整理数据;2. 控制排序优先级(先按一列,再按另一列);3. 让数据输出更有结构、更容易看懂。

多列排序的语法

要按多列排序,用的还是熟悉的ORDER BY,不过这次你要用逗号把多个列名分开。PostgreSQL会先按第一个列排,如果有一样的,再按第二个,以此类推。

通用语法如下:

SELECT 列们
FROM 表
ORDER BY 列1 排序1,  列2 排序2, ... ;

这里:

  • 列1列2、... —— 就是你想排序的那些列。
  • 排序1排序2、... —— 排序方向(ASC 升序,DESC 降序)。
  • 这个参数可选,默认是ASC

例子1:先按姓再按名排序学生

假设有个students表,里面是学生信息:

id first_name last_name age
1 Anna Lin 20
2 Victor Lin 22
3 Maria Kim 21
4 Otto Lin 23
5 Anna Kim 20

我们的目标——先按姓(last_name),再按名(first_name)排序学生。

SELECT id, first_name, last_name, age
FROM students
ORDER BY last_name ASC, first_name ASC;

结果:

id first_name last_name age
5 Anna Kim 20
3 Maria Kim 21
1 Anna Lin 20
4 Otto Lin 23
2 Victor Lin 22

可以看到,先按姓(Kim,然后Lin)排,再按名(Anna、Maria等)。这种方式特别适合你要快速找人,或者要把名单排好序的时候。

例子2:按订单日期和金额排序

假设有个orders表,里面是订单信息:

order_id customer_id order_date total
1 101 2025-10-01 500
2 102 2025-10-03 200
3 103 2025-10-02 300
4 104 2025-10-01 100
5 101 2025-10-03 600

我们想先按order_date排,再按total降序排。

SQL查询:

SELECT order_id, customer_id, order_date, total
FROM orders
ORDER BY order_date ASC, total DESC;

结果:

order_id customer_id order_date total
1 101 2025-10-01 500
4 104 2025-10-01 100
3 103 2025-10-02 300
5 101 2025-10-03 600
2 102 2025-10-03 200

可以看到,同一天的订单会再按金额排。

排序时处理NULLNULLS FIRSTNULLS LAST

SQL里有个特殊值——NULL,意思是“没值”。具体怎么用以后再说,不过现在正好可以看看排序时怎么控制它。

当你排序的列里有NULL,PostgreSQL得决定这些空值放哪:开头还是结尾。

默认情况下:

  • ORDER BY ... ASC时:NULL排在最后NULLS LAST
  • ORDER BY ... DESC时:NULL排在最前面NULLS FIRST

有时候你不喜欢默认的,你可以用NULLS FIRSTNULLS LAST手动指定。

语法:

ORDER BY 列 ASC NULLS FIRST
ORDER BY 列 DESC NULLS LAST

例子:按成绩排序,NULL表示“还没打分”

SELECT student_id, grade
FROM grades
ORDER BY grade DESC NULLS LAST;

这样你会先看到分高的,再看到分低的,最后才是还没打分(NULL)的。

反过来——先显示没分的学生

假设有个grades表,有些学生还没分数(NULL):

student_id grade
101 NULL
102 85
103 NULL
104 92
105 76

我们想先把没分的学生排前面,后面再按分数升序排其他学生。

SELECT student_id, grade
FROM grades
ORDER BY grade ASC NULLS FIRST;

结果:

student_id grade
101 NULL
103 NULL
105 76
102 85
104 92

NULLS FIRST配合ORDER BY grade ASC,就能保证NULL的记录在最前面,后面才是分数升序。

注意事项和常见错误

新手经常忘了给每个列写排序方向。如果你没写,PostgreSQL默认用ASC。还有一个常见坑,就是忘了ORDER BY里列的顺序很重要:先按第一个列排,只有第一个列一样时才按第二个列排。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION