CodeGym /課程 /SQL SELF /使用 OFFSET 來跳過資料列和建立分頁

使用 OFFSET 來跳過資料列和建立分頁

SQL SELF
等級 3, 課堂 1
開放

先問你一個問題:你在網購網站看到一堆商品都塞在同一頁時會怎麼辦?沒錯,就是點下一頁。那你知道背後發生什麼事嗎?其實就是 SQL 的魔法啦 —— 用 OFFSET 這個指令來跳過資料列。今天要跟你聊聊什麼是 OFFSET、它有什麼用、怎麼用,還有為什麼它是分頁功能的基礎。

OFFSET 是 SQL 裡的一個關鍵字,可以讓你在查詢結果裡跳過指定數量的資料列。就像翻書一樣:你可以「跳過」前 10 行,直接從第 11 行開始看。

語法

SELECT 欄位1, 欄位2
FROM 表格
OFFSET 跳過_幾行;
  • OFFSET —— 跳過資料列的關鍵字。
  • 跳過_幾行 —— 你想要跳過的資料列數量。

OFFSET 的簡單範例

假設我們有一個 students 表格,裡面有這些資料:

id name age
1 愛麗絲 22
2 鮑勃 24
3 克拉拉 23
4 丹 21
5 伊娃 25

我們想要從第三個學生開始顯示。可以這樣查:

SELECT *
FROM students
OFFSET 2;

結果:

id name age
3 克拉拉 23
4 丹 21
5 伊娃 25

SQL「跳過」了前兩行(愛麗絲和鮑勃),從第三行開始給你結果。就像用書籤一樣:「這頁看過了,翻下一頁」。

OFFSET 跟 LIMIT 一起用

OFFSET 通常會跟 LIMIT 一起用。這樣你可以同時跳過幾行,又只拿你要的那幾筆資料。這對做分頁(page = 頁面)超級有用 —— 一次顯示幾行資料。

假設我們想每次顯示 2 筆,從第三行開始。查詢會長這樣:

SELECT *
FROM students
LIMIT 2 
OFFSET 2;

結果:

id name age
3 克拉拉 23
4 丹 21

邏輯是這樣:

  1. OFFSET 2 先跳過前兩行:愛麗絲和鮑勃。
  2. LIMIT 2 再從剩下的拿兩行。

分頁怎麼做

現在來到最有趣的部分 —— 分頁啦。想像你要做一個有學生列表的網頁,每頁只想顯示 2 筆資料。怎麼辦?

基本原則:

  • 第一頁不跳過任何行:OFFSET 0。
  • 第二頁跳過 2 行:OFFSET 2。
  • 第三頁跳過 4 行:OFFSET 4。
  • 以此類推...

範例:顯示第二頁

第一頁會顯示第 1 和 2 筆(愛麗絲和鮑勃)。第二頁就是第 3 和 4 筆(克拉拉和丹)。

SELECT *
FROM students
ORDER BY id
LIMIT 2 
OFFSET 2;

結果:

id name age
3 克拉拉 23
4 丹 21

範例:顯示第三頁

第三頁會是第 5 和 6 筆(如果有的話)。

SELECT *
FROM students
ORDER BY id
LIMIT 2 
OFFSET 4;

結果:

id name age
5 伊娃 25

OFFSET 計算公式

做分頁系統時,可以用這個公式自動算 OFFSET:

OFFSET = (頁碼 - 1) * 每頁_幾筆

舉例:

  • 第一頁:(1 - 1) * 2 = 0。
  • 第二頁:(2 - 1) * 2 = 2。
  • 第三頁:(3 - 1) * 2 = 4。

效能注意事項

當你在大表格裡用 OFFSET,尤其是很後面的頁面時,效能可能會變差。因為 PostgreSQL 還是會把被跳過的資料列都掃過一遍。比如 OFFSET 10000,資料庫還是會先看過前一萬行才給你結果。這時可以考慮其他做法,比如用唯一 id 當分頁的標記。

替代方案:用游標分頁

想優化的話,可以用「游標」的方式。不是用 OFFSET 跳過資料列,而是記住上一頁最後一筆的 id,下次查詢時用這個 id 當條件:

SELECT *
FROM students
WHERE id > 最後_顯示的_id
ORDER BY id
LIMIT 2;

這種做法在大表格時會快很多。

分頁的實際應用

分頁 在大多數網頁應用都會用到:網購、部落格、後台管理面板。舉例:

  • 網購網站商品列表;
  • CRM 系統的用戶列表;
  • 新聞動態分頁顯示。

分析大量資料時,分頁也很有用,可以分批處理。

用 OFFSET 常見錯誤

剛學 OFFSET 時常常會踩雷,這裡列幾個常見錯誤:

沒加排序。 如果你沒加 ORDER BY,OFFSET 的結果順序可能亂七八糟。

錯誤查詢:

SELECT * FROM students
OFFSET 5;

正確查詢:

SELECT * FROM students
ORDER BY id
OFFSET 5;

OFFSET 值設錯。 如果設太大,結果會是空的。

效能問題。 剛剛說過,OFFSET 很大時效能會很差。

沒加過濾。 如果你用 OFFSET 跟 LIMIT 但沒加 WHERE 過濾,可能會撈到一堆你不想要的資料,效能也會變差。

指令順序。 SQL 指令順序很嚴格:要先 LIMIT,再 OFFSET。可以省略,但不能顛倒順序。

2
任務
SQL SELF, 等級 3, 課堂 1
上鎖
使用 `OFFSET` 跳過資料列
使用 `OFFSET` 跳過資料列
2
任務
SQL SELF, 等級 3, 課堂 1
上鎖
分頁顯示資料
分頁顯示資料
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION