Bài 2. SELECT: truy vấn dữ liệu cơ bản

SELECT là lệnh dùng nhiều nhất. Bài này học chọn cột, đặt bí danh, loại trùng, lọc với WHERE và các toán tử so sánh, logic, sắp xếp ORDER BY và giới hạn LIMIT để phân trang.

45 phútCơ bản
Bạn sẽ học được
  • Chọn cột, dùng bí danh AS, biểu thức tính toán
  • Lọc với WHERE: so sánh, AND/OR/NOT
  • Loại trùng với DISTINCT
  • Sắp xếp ORDER BY, giới hạn LIMIT/OFFSET

Khái niệm và lý thuyết

Thứ tự viết: SELECT cột FROM bảng WHERE điều_kiện ORDER BY cột LIMIT n. Thứ tự thực hiện lại là FROM → WHERE → SELECT → ORDER BY → LIMIT: vì vậy bí danh đặt ở SELECT dùng được trong ORDER BY nhưng không dùng được trong WHERE.

Chọn cột, bí danh, biểu thức

SELECT * FROM sinhvien;                         -- mọi cột (chỉ nên dùng khi thử)
SELECT ma_sv, ho_ten, que_quan FROM sinhvien;
SELECT ho_ten AS 'Họ tên', que_quan AS que FROM sinhvien;
SELECT ho_ten, YEAR(CURDATE()) - YEAR(ngay_sinh) AS tuoi FROM sinhvien;
SELECT ten_mon, so_tin_chi * 15 AS so_tiet FROM monhoc;
SELECT DISTINCT que_quan FROM sinhvien;                -- mỗi quê một dòng
SELECT COUNT(*) AS so_sv FROM sinhvien;

WHERE: lọc dữ liệu

SELECT ho_ten, que_quan FROM sinhvien WHERE que_quan = 'Sơn La';
SELECT ho_ten, ngay_sinh FROM sinhvien WHERE ngay_sinh >= '2006-01-01';
SELECT ho_ten FROM sinhvien WHERE gioi_tinh = 'Nữ' AND lop_id = 2;
SELECT ho_ten FROM sinhvien WHERE que_quan = 'Sơn La' OR que_quan = 'Điện Biên';
SELECT ho_ten FROM sinhvien WHERE NOT que_quan = 'Sơn La';
SELECT ho_ten FROM sinhvien WHERE lop_id = 1 AND (que_quan = 'Sơn La' OR gioi_tinh = 'Nữ');  -- ngoặc!
SELECT * FROM diem WHERE diem <> 8.5;      -- khác; != cũng được
Toán tửÝ nghĩa
= <> != < > <= >=So sánh
AND OR NOTLogic; AND ưu tiên hơn OR
BETWEEN a AND bTrong khoảng (bài 3)
IN (...)Thuộc tập (bài 3)
LIKESo khớp mẫu (bài 3)
IS NULLRỗng (bài 3)

ORDER BY và LIMIT

SELECT ho_ten, ngay_sinh FROM sinhvien ORDER BY ho_ten;             -- tăng dần (ASC)
SELECT ho_ten, ngay_sinh FROM sinhvien ORDER BY ngay_sinh DESC;      -- giảm dần
SELECT * FROM sinhvien ORDER BY lop_id, ho_ten;                      -- nhiều cột
SELECT * FROM diem ORDER BY diem DESC LIMIT 3;                       -- top 3
SELECT * FROM sinhvien ORDER BY id LIMIT 2 OFFSET 2;                 -- trang 2, mỗi trang 2 dòng
SELECT * FROM sinhvien ORDER BY id LIMIT 2, 2;                       -- cách viết khác: OFFSET, COUNT
-- Sắp xếp tên tiếng Việt theo tên rồi họ
SELECT ho_ten FROM sinhvien ORDER BY SUBSTRING_INDEX(ho_ten, ' ', -1), ho_ten;

Phân trang trong PHP: trang p, mỗi trang n → LIMIT n OFFSET (p-1)*n. Luôn có ORDER BY khi dùng LIMIT, nếu không thứ tự không bảo đảm.

Mẹo hay

Trong phpMyAdmin, bấm vào tiêu đề cột để sắp xếp và xem câu SQL tương ứng ở trên bảng: cách học ORDER BY rất trực quan.

Lưu ý

So sánh chuỗi với collation _ci không phân biệt hoa thường: que_quan = 'sơn la' vẫn khớp 'Sơn La'. Cần phân biệt thì dùng BINARY.

Thực hành
  1. Liệt kê họ tên, tuổi của sinh viên nữ, sắp theo tuổi giảm dần.
  2. Lấy 3 điểm cao nhất của môn có id = 1.
  3. Liệt kê sinh viên quê Sơn La hoặc Điện Biên, thuộc lớp 1, sắp theo tên.
  4. Viết truy vấn phân trang: trang 2, mỗi trang 2 sinh viên, sắp theo mã.
Tóm tắt bài học
  • SELECT cột AS bí_danh FROM bảng; DISTINCT bỏ trùng.
  • WHERE lọc với so sánh và AND/OR/NOT; dùng ngoặc khi trộn.
  • ORDER BY ASC/DESC, nhiều cột.
  • LIMIT n OFFSET m để phân trang.