Học bằng cách đọc theo thứ tự

DISTINCT, ORDER BY, LIMIT — Định hình tập kết quả

Học SQL DISTINCT, ORDER BY, LIMIT và OFFSET. Bao gồm loại trùng lặp, sắp xếp, giới hạn hàng, và phân trang với OFFSET — tất cả chạy trực tiếp trên trình duyệt với tập dữ liệu score nạp từ CSV.

Dữ liệu sẽ dùng — bảng score nạp từ CSV

Bài này dùng bảng `score` được nạp tự động từ một file CSV để đi qua bốn cấu trúc định hình đầu ra của SELECTDISTINCT (loại trùng lặp), ORDER BY (sắp xếp), LIMIT (số hàng), và OFFSET (bỏ qua từ đầu).

Bảng score có 5 cột — id / name / subject / score / recorded_on — với tổng cộng 15 hàng: 5 học viên (Alice / Bob / Carol / Dave / Eve) mỗi người làm 3 môn (Math / English / Science).

Trước các bài tập, hãy xác nhận định nghĩa cộtmột mẫu dữ liệu của bảng score.

① Chạy PRAGMA table_info(score); để kiểm tra tên cột, kiểu, và khóa chính.

② Chạy SELECT * FROM score LIMIT 5; để xem trước 5 hàng đầu.

SQL Editor

Chạy truy vấn để xem kết quả

DISTINCT — chỉ trả về các hàng duy nhất

Một kết quả SELECT có thể chứa cùng một hàng nhiều lần. Ví dụ, lấy chỉ cột name từ score trả về 15 hàng — Alice / Bob / Carol / Dave / Eve, mỗi người ba môn.

Viết `SELECT DISTINCT col, ...` gộp các hàng trùng lặp thành một trong tập kết quả. Với nhiều cột, các hàng được coi là trùng lặp khi tổ hợp các cột khớp nhau.

Cách DISTINCT hoạt động
SELECT name FROM score;SELECT DISTINCT name FROM score;AliceAliceAliceBobAliceCarolBobDaveBob ...EveTổng 15 hàng (có trùng lặp)Tổng 5 hàng (sau khi loại trùng)
SELECT không có DISTINCT trả về các hàng trùng lặp như vốn có; với DISTINCT, các hàng cùng giá trị gộp lại thành một.
-- Liệt kê các tên học viên duy nhất
SELECT DISTINCT name FROM score;

-- Liệt kê các môn học duy nhất
SELECT DISTINCT subject FROM score;

-- Loại trùng theo tổ hợp (name, subject) (= cả 15 hàng đều duy nhất)
SELECT DISTINCT name, subject FROM score;

Chạy hai truy vấn cạnh nhau trong một console để thấy kết quả thay đổi ra sao khi có và không có DISTINCT. (Khi bạn chạy đúng, phần giải thích sẽ hiện ra.)

① Từ score, lấy cột name không có `DISTINCT`.

② Trong cùng console, lấy cột name có `DISTINCT`.

③ Xác nhận cái đầu trả về 15 hàng (mỗi tên 3 lần), và cái thứ hai trả về 5 hàng (các trùng lặp đã gộp).

SQL Editor

Chạy truy vấn để xem kết quả

ORDER BY — sắp xếp kết quả

SQL không đảm bảo thứ tự hàng mặc định — SELECT * FROM score; để DB tự quyết định thứ tự hàng trả về. Khi bạn muốn một thứ tự cụ thể, thêm `ORDER BY col [ASC|DESC]`.

- ASC (tăng dần / nhỏ → lớn) là mặc định và có thể bỏ

- DESC (giảm dần / lớn → nhỏ) phải được viết rõ ràng

- Một danh sách nhiều cột ngăn cách bằng dấu phẩy cho bạn sắp xếp đa cấp: các hàng bằng nhau ở cột đầu được sắp theo cột thứ hai

ORDER BY tăng dần và giảm dần
Gốc(không thứ tự)ORDER BY score(ASC = tăng dần)ORDER BY score DESC(giảm dần)Alice 92Dave 65Carol 95Bob 76Bob 76Alice 92Carol 95Eve 87Eve 87Dave 65Alice 92Bob 76Eve 87Carol 95Dave 65
Không có ORDER BY, thứ tự không được đảm bảo; chỉ định ASC / DESC tạo ra thứ tự bạn muốn. Mặc định là ASC (tăng dần).
-- 1) Tăng dần một cột (ASC có thể bỏ)
SELECT name, score FROM score ORDER BY score;

-- 2) Giảm dần một cột
SELECT name, score FROM score ORDER BY score DESC;

-- 3) Sắp xếp nhiều cột (theo subject, rồi điểm cao nhất trước trong cùng subject)
SELECT name, subject, score FROM score ORDER BY subject ASC, score DESC;

Chi tiết về ORDER BY

- ORDER BY đặt sau `WHERE` và trước `LIMIT`. Nhớ thứ tự SELECT cols FROM table WHERE condition ORDER BY col DESC LIMIT N; thì bạn sẽ không bị nhầm.

- Vế phải của ORDER BY có thể nhận số cột (ORDER BY 2 DESC sắp theo cột thứ 2 được chọn), nhưng nó hại cho khả năng đọc — quy ước là dùng tên cột.

- Trong console của khóa học này, sắp chuỗi là chữ hoa → chữ thường (thứ tự ASCII). Một số DB coi 'A''a' là tương đương.

Hãy hình dung một màn hình danh sách điểm nơi bạn muốn học viên được sắp theo name, và trong mỗi học viên, môn có điểm thấp nhất hiển thị trước.

① Từ score, lấy các cột name, subject, và score.

② Sắp theo `name` tăng dần, và trong cùng name theo `score` tăng dần.

③ Xác nhận kết quả là 15 hàng, bắt đầu với Alice Science 78 và kết thúc với Eve English 93.

SQL Editor

Chạy truy vấn để xem kết quả

Cùng thứ tự name như Bài tập 2, nhưng lần này bạn muốn các môn điểm cao nhất hiển thị trước trong mỗi học viên.

① Từ score, lấy các cột name, subject, và score.

② Sắp theo `name` tăng dần, và trong cùng name theo `score` giảm dần.

③ Xác nhận kết quả là 15 hàng, bắt đầu với Alice Math 92 và kết thúc với Eve Science 86.

SQL Editor

Chạy truy vấn để xem kết quả

LIMIT và OFFSET — thu hẹp số lượng và phân trang

Khi tập kết quả lớn — 100 hàng, 10.000 hàng — đổ tất cả lên màn hình thì nặng và người dùng không tiếp nhận hết được. Thêm `LIMIT N` chỉ trả về N hàng đầu. Kết hợp với `OFFSET M` để bỏ qua M hàng đầu rồi lấy N, cho bạn phân trang cho những thứ như "item 6–10" hoặc "item 11–20."

Phân trang với LIMIT và OFFSET
Sau ORDER BY(toàn bộ 7 hàng)LIMIT 3(trang 1)LIMIT 3 OFFSET 3(trang 2)1st Carol 95lấybỏ qua2nd Eve 93lấybỏ qua3rd Alice 92lấybỏ qua4th Bob 90lấy5th Bob 88lấy6th Eve 87lấy7th Eve 86
So với kết quả đã sắp ORDER BY, LIMIT quyết định "lấy bao nhiêu" và OFFSET quyết định "bỏ qua bao nhiêu từ đầu." Công thức cơ bản là OFFSET = (số trang - 1) × số hàng mỗi trang.
-- 1) Lấy top 5 (xếp hạng TOP 5)
SELECT name, subject, score FROM score
ORDER BY score DESC
LIMIT 5;

-- 2) Lấy item 6 đến 10 (trang 2)
SELECT name, subject, score FROM score
ORDER BY score DESC
LIMIT 5 OFFSET 5;

-- 3) Công thức phân trang: trang N, K hàng mỗi trang
--    LIMIT K OFFSET (N - 1) * K
--    ví dụ trang 3, 5 mỗi trang → LIMIT 5 OFFSET 10
TrangHàng mỗi trangOFFSETLIMITHạng đích
15051–5
25556–10
3510511–15
1100101–10
210101011–20
1200201–20

LIMIT không có ORDER BY không đảm bảo thứ tự

Viết chỉ `LIMIT` và bỏ qua `ORDER BY` như SELECT * FROM score LIMIT 5; để DB tự chọn 5 hàng nào trả về. Kể cả trên DB có xu hướng trả hàng theo thứ tự insert (như SQLite), chuẩn SQL nói thứ tự không xác định. Trên MySQL / PostgreSQL, index và execution plan có thể đổi hàng nào bạn nhận.

Cho bất cứ thứ gì mà thứ tự quan trọng — xếp hạng, phân trang, "N item đầu" — luôn viết `ORDER BY` trước `LIMIT`.

Hãy hình dung một dashboard cần widget "top 5 trên tất cả các môn."

① Từ score, lấy các cột name, subject, và score.

② Sắp theo `score` giảm dần, và chỉ lấy 5 hàng đầu.

③ Xác nhận kết quả là 5 hàng, bắt đầu với Carol Math 95 và kết thúc với Bob English 88.

SQL Editor

Chạy truy vấn để xem kết quả

Hãy hình dung một nút "Hiển thị thêm" trên dashboard nạp 5 item tiếp theo sau top 5.

① Cùng thứ tự sắp như Bài tập 4 (score giảm dần), lấy các cột name, subject, và score.

Bỏ qua 5 hàng đầu và lấy 5 hàng tiếp theo (hạng 6–10).

③ Xác nhận kết quả là 5 hàng, bắt đầu với Eve Math 87 và kết thúc với Alice Science 78.

SQL Editor

Chạy truy vấn để xem kết quả
QUIZ

Kiểm tra kiến thức

Hãy trả lời từng câu hỏi một.

Câu 1Câu nào sau đây mô tả đúng SELECT DISTINCT?

Câu 2SELECT name, score FROM score ORDER BY score DESC; trả về gì?

Câu 3SELECT * FROM score ORDER BY score DESC LIMIT 5 OFFSET 10; trả về những hàng nào?