在 SQL 查詢中,我們常需要 “按報名時間先后看活動名單”“只看第 2 頁的活動報名數據”—— 這些需求靠基礎查詢無法實現,而ORDER BY(排序) 和LIMIT(分頁) 就是解決這類問題的核心工具。今天我們用 “校園活動報名記錄表” 為案例,從零學會排序和分頁的用法,代碼可直接復制運行,看完就能上手。
我整理了超多的學習資料,包含專業、課程、考試等資源,還有游戲和軟件合集
學習資料合集文檔https://www.kdocs.cn/l/cjchDXwklk1B
一、先搞懂:為什么需要排序與分頁?
先想兩個場景:
- 學校舉辦 “校園歌手大賽”,收集到 100 條報名數據,想按 “報名時間從晚到早” 看最新報名的同學,或按 “學院 + 報名時間” 分組排序 —— 這需要ORDER BY;
- 報名數據太多,一頁顯示 20 條,想查看第 2 頁(21-40 條)或第 3 頁(41-60 條)的數據,避免一次性加載所有數據卡頓 —— 這需要LIMIT。
核心作用:
- ORDER BY:讓查詢結果按指定規則排序,避免數據雜亂無章;
- LIMIT:限制查詢結果的行數,實現分頁加載,提升效率。
準備案例數據:校園活動報名記錄表
我們創建全新的 “校園活動報名記錄表”(表名:campus_activity_signup),包含報名 ID、學生信息、活動信息、報名時間等字段,代碼可直接運行:
-- 創建校園活動報名記錄表
CREATE TABLE campus_activity_signup (signup_id INT PRIMARY KEY AUTO_INCREMENT, -- 報名ID(自增,唯一標識)student_id CHAR(10) NOT NULL, -- 學號(如2025001001)student_name VARCHAR(20) NOT NULL, -- 學生姓名college VARCHAR(30) NOT NULL, -- 所屬學院(如計算機學院、文學院)activity_name VARCHAR(50) NOT NULL, -- 活動名稱(如校園歌手大賽、運動會)signup_time DATETIME NOT NULL, -- 報名時間signup_status VARCHAR(10) NOT NULL -- 報名狀態(已確認、待確認、已取消)
);-- 插入15條測試數據(覆蓋不同學院、活動、報名時間)
INSERT INTO campus_activity_signup (student_id, student_name, college, activity_name, signup_time, signup_status)
VALUES
('2025001001', '張三', '計算機學院', '校園歌手大賽', '2025-09-01 08:30:00', '已確認'),
('2025002001', '李四', '文學院', '校園歌手大賽', '2025-09-01 09:15:00', '已確認'),
('2025003001', '王五', '商學院', '運動會', '2025-09-01 10:00:00', '待確認'),
('2025001002', '趙六', '計算機學院', '運動會', '2025-09-01 10:20:00', '已確認'),
('2025002002', '孫七', '文學院', '校園歌手大賽', '2025-09-02 08:45:00', '待確認'),
('2025003002', '周八', '商學院', '校園歌手大賽', '2025-09-02 09:30:00', '已確認'),
('2025001003', '吳九', '計算機學院', '運動會', '2025-09-02 11:00:00', '已取消'),
('2025002003', '鄭十', '文學院', '運動會', '2025-09-03 09:00:00', '已確認'),
('2025003003', '錢十一', '商學院', '校園歌手大賽', '2025-09-03 10:15:00', '待確認'),
('2025004001', '馮十二', '外國語學院', '校園歌手大賽', '2025-09-03 14:20:00', '已確認'),
('2025004002', '陳十三', '外國語學院', '運動會', '2025-09-04 08:50:00', '待確認'),
('2025001004', '褚十四', '計算機學院', '校園歌手大賽', '2025-09-04 09:40:00', '已確認'),
('2025002004', '衛十五', '文學院', '校園歌手大賽', '2025-09-04 10:30:00', '已取消'),
('2025003004', '蔣十六', '商學院', '運動會', '2025-09-05 09:10:00', '已確認'),
('2025004003', '沈十七', '外國語學院', '運動會', '2025-09-05 11:20:00', '待確認');-- 查看表數據(確認插入成功)
SELECT * FROM campus_activity_signup LIMIT 5;
表中數據如下(簡化展示):
signup_id | student_id | student_name | college | activity_name | signup_time | signup_status |
1 | 2025001001 | 張三 | 計算機學院 | 校園歌手大賽 | 2025-09-01 08:30:00 | 已確認 |
2 | 2025002001 | 李四 | 文學院 | 校園歌手大賽 | 2025-09-01 09:15:00 | 已確認 |
3 | 2025003001 | 王五 | 商學院 | 運動會 | 2025-09-01 10:00:00 | 待確認 |
4 | 2025001002 | 趙六 | 計算機學院 | 運動會 | 2025-09-01 10:20:00 | 已確認 |
5 | 2025002002 | 孫七 | 文學院 | 校園歌手大賽 | 2025-09-02 08:45:00 | 待確認 |
二、ORDER BY:實現排序查詢
ORDER BY是 SQL 中用于排序的關鍵字,支持 “單字段排序” 和 “多字段排序”,還能指定 “升序” 或 “降序”。
1. 基礎用法:單字段排序(升序 / 降序)
語法:SELECT 字段 FROM 表名 ORDER BY 排序字段 [ASC/DESC];
- ASC:升序(默認,可省略),比如時間從早到晚、數字從小到大;
- DESC:降序,比如時間從晚到早、數字從大到小。
例子 1:按報名時間降序,查看最新報名的同學
需求:查看 “校園歌手大賽” 的報名數據,按 “報名時間從晚到早” 排序,顯示學生姓名、學院、報名時間。
代碼:
SELECT student_name AS 學生姓名,college AS 所屬學院,signup_time AS 報名時間
FROM campus_activity_signup
WHERE activity_name = '校園歌手大賽' -- 只看校園歌手大賽的報名
ORDER BY signup_time DESC; -- 按報名時間降序(最新的在前)
運行結果(前 5 條):
學生姓名 | 所屬學院 | 報名時間 |
衛十五 | 文學院 | 2025-09-04 10:30:00 |
褚十四 | 計算機學院 | 2025-09-04 09:40:00 |
馮十二 | 外國語學院 | 2025-09-03 14:20:00 |
錢十一 | 商學院 | 2025-09-03 10:15:00 |
周八 | 商學院 | 2025-09-02 09:30:00 |
可以看到:最新的報名記錄(2025-09-04 10:30)排在最前面,符合 “降序” 需求。
例子 2:按報名狀態升序,查看不同狀態的報名數據
需求:查看 “運動會” 的報名數據,按 “報名狀態(已確認→待確認→已取消)” 升序排序,顯示學生姓名、狀態、報名時間。
代碼:
SELECT student_name AS 學生姓名,signup_status AS 報名狀態,signup_time AS 報名時間
FROM campus_activity_signup
WHERE activity_name = '運動會'
ORDER BY signup_status ASC; -- 按狀態升序(默認按字符順序排序)
運行結果:
學生姓名 | 報名狀態 | 報名時間 |
趙六 | 已確認 | 2025-09-01 10:20:00 |
鄭十 | 已確認 | 2025-09-03 09:00:00 |
蔣十六 | 已確認 | 2025-09-05 09:10:00 |
王五 | 待確認 | 2025-09-01 10:00:00 |
陳十三 | 待確認 | 2025-09-04 08:50:00 |
沈十七 | 待確認 | 2025-09-05 11:20:00 |
吳九 | 已取消 | 2025-09-02 11:00:00 |
解釋:字符型字段按 “拼音首字母順序” 排序,“已確認”(Y)在 “待確認”(D)之后?不對,這里實際是按 “ASCII 碼順序” 排序 ——“待” 的 ASCII 碼比 “已” 小,所以 “待確認” 會排在 “已確認” 前面?別糾結細節,記住:想按自定義順序排序(如 “已確認→待確認→已取消”),后續可學FIELD()函數,入門階段先掌握基礎排序邏輯即可。
2. 進階用法:多字段排序
當 “單字段排序無法區分順序” 時,需要用 “多字段排序”—— 先按第一個字段排序,第一個字段相同的,再按第二個字段排序。
例子 3:按 “學院 + 報名時間” 排序,查看同一學院的報名順序
需求:查看所有活動的報名數據,先按 “學院升序”(同一學院的排在一起),同一學院內按 “報名時間降序”(最新報名的在前),顯示學院、學生姓名、活動名稱、報名時間。
代碼:
SELECT college AS 所屬學院,student_name AS 學生姓名,activity_name AS 活動名稱,signup_time AS 報名時間
FROM campus_activity_signup
-- 多字段排序:先按學院升序,再按報名時間降序
ORDER BY college ASC, signup_time DESC;
運行結果(計算機學院部分):
所屬學院 | 學生姓名 | 活動名稱 | 報名時間 |
計算機學院 | 褚十四 | 校園歌手大賽 | 2025-09-04 09:40:00 |
計算機學院 | 吳九 | 運動會 | 2025-09-02 11:00:00 |
計算機學院 | 趙六 | 運動會 | 2025-09-01 10:20:00 |
計算機學院 | 張三 | 校園歌手大賽 | 2025-09-01 08:30:00 |
可以看到:所有 “計算機學院” 的學生排在一起,且同一學院內,報名時間晚的(2025-09-04)排在前面,符合 “多字段排序” 的邏輯。
關鍵規則:ORDER BY后字段的順序很重要,先按第一個字段排序,第一個字段相同的才會按第二個字段排序,以此類推。
三、LIMIT:實現分頁查詢
當查詢結果有幾十、幾百條時,一次性顯示會很雜亂,用LIMIT可以 “按頁顯示”,比如每頁顯示 5 條,查看第 1 頁(1-5 條)、第 2 頁(6-10 條)等。
1. 基礎用法:限制返回行數(LIMIT N)
語法:SELECT 字段 FROM 表名 LIMIT 行數;
作用:只返回查詢結果的前 N 行數據。
例子 4:查看 “已確認” 狀態的前 3 條報名數據
需求:查看所有 “報名狀態為已確認” 的數據,只顯示前 3 條,按報名時間降序。
代碼:
SELECT student_name AS 學生姓名,activity_name AS 活動名稱,signup_time AS 報名時間
FROM campus_activity_signup
WHERE signup_status = '已確認'
ORDER BY signup_time DESC
LIMIT 3; -- 只返回前3條數據
運行結果:
學生姓名 | 活動名稱 | 報名時間 |
蔣十六 | 運動會 | 2025-09-05 09:10:00 |
褚十四 | 校園歌手大賽 | 2025-09-04 09:40:00 |
馮十二 | 校園歌手大賽 | 2025-09-03 14:20:00 |
2. 進階用法:分頁查詢(LIMIT 偏移量,行數)
語法:SELECT 字段 FROM 表名 LIMIT 偏移量, 每頁行數;
- 偏移量:從第幾條數據開始(注意:SQL 中數據從 0 開始計數,不是 1);
- 每頁行數:每頁顯示多少條數據。
分頁公式(重要):
想查看第 M 頁,每頁顯示 N 條數據:
偏移量 = (M - 1) * N,LIMIT 偏移量, N
比如:
- 第 1 頁(1-5 條):M=1,N=5 → 偏移量 = 0 → LIMIT 0, 5;
- 第 2 頁(6-10 條):M=2,N=5 → 偏移量 = 5 → LIMIT 5, 5;
- 第 3 頁(11-15 條):M=3,N=5 → 偏移量 = 10 → LIMIT 10, 5。
例子 5:分頁查看所有報名數據(每頁 5 條,查看第 2 頁)
需求:查看所有報名數據,按報名時間降序,每頁顯示 5 條,查看第 2 頁(6-10 條)。
代碼:
SELECT signup_id AS 報名ID,student_name AS 學生姓名,activity_name AS 活動名稱,signup_time AS 報名時間
FROM campus_activity_signup
ORDER BY signup_time DESC
-- 第2頁,每頁5條:偏移量=(2-1)*5=5,所以LIMIT 5,5
LIMIT 5, 5;
運行結果(第 2 頁,6-10 條):
報名 ID | 學生姓名 | 活動名稱 | 報名時間 |
12 | 褚十四 | 校園歌手大賽 | 2025-09-04 09:40:00 |
11 | 陳 |