Bài 5: Truy Vấn Cơ Bản – SELECT
Giai đoạn 2 – Truy Vấn Dữ Liệu · Mục tiêu: Thành thạo câu lệnh SELECT với các kỹ thuật lọc, sắp xếp và giới hạn kết quả.
1. Câu lệnh SELECT cơ bản
Lấy tất cả cột
SELECT * FROM SanPham;
Lấy một số cột cụ thể
SELECT TenSP, Gia, SoLuongTon FROM SanPham;
Đặt tên hiển thị cho cột (Alias)
SELECT
TenSP AS 'Tên sản phẩm',
Gia AS 'Giá bán (VNĐ)',
SoLuongTon AS 'Tồn kho'
FROM SanPham;
Loại bỏ giá trị trùng – DISTINCT
-- Liệt kê các danh mục sản phẩm (không trùng)
SELECT DISTINCT DanhMuc FROM SanPham;
-- Liệt kê các thành phố khách hàng đến từ
SELECT DISTINCT ThanhPho FROM KhachHang;
2. Lọc dữ liệu – WHERE
Cú pháp
SELECT cot1, cot2 FROM ten_bang WHERE dieu_kien;
Toán tử so sánh
| Toán tử | Ý nghĩa | Ví dụ |
|---|---|---|
= | Bằng | WHERE DanhMuc = 'Điện thoại' |
!= hoặc <> | Khác | WHERE TrangThai != 'Đã huỷ' |
> | Lớn hơn | WHERE Gia > 10000000 |
< | Nhỏ hơn | WHERE SoLuongTon < 10 |
>= | Lớn hơn hoặc bằng | WHERE DiemTB >= 8 |
<= | Nhỏ hơn hoặc bằng | WHERE Tuoi <= 30 |
Ví dụ
-- Sản phẩm có giá trên 20 triệu
SELECT TenSP, Gia FROM SanPham WHERE Gia > 20000000;
-- Đơn hàng đang chờ xác nhận
SELECT * FROM DonHang WHERE TrangThai = 'Chờ xác nhận';
-- Nhân viên có lương >= 15 triệu
SELECT HoTen, Luong FROM NhanVien WHERE Luong >= 15000000;
3. Toán tử logic – AND, OR, NOT
AND – Tất cả điều kiện đều đúng
-- Điện thoại có giá dưới 25 triệu
SELECT TenSP, Gia
FROM SanPham
WHERE DanhMuc = 'Điện thoại' AND Gia < 25000000;
OR – Ít nhất 1 điều kiện đúng
-- Sản phẩm là Điện thoại HOẶC Laptop
SELECT TenSP, DanhMuc, Gia
FROM SanPham
WHERE DanhMuc = 'Điện thoại' OR DanhMuc = 'Laptop';
NOT – Phủ định điều kiện
-- Đơn hàng KHÔNG bị huỷ
SELECT * FROM DonHang WHERE NOT TrangThai = 'Đã huỷ';
Kết hợp AND, OR (dùng ngoặc)
-- Điện thoại hoặc Laptop có giá dưới 30 triệu
SELECT TenSP, DanhMuc, Gia
FROM SanPham
WHERE (DanhMuc = 'Điện thoại' OR DanhMuc = 'Laptop')
AND Gia < 30000000;
:::warning Ưu tiên toán tử
AND được thực hiện trước OR. Hãy luôn dùng ngoặc tròn () để rõ ràng:
-- Có thể hiểu sai
WHERE A = 1 OR B = 2 AND C = 3
-- Thực tế: WHERE A = 1 OR (B = 2 AND C = 3)
-- Rõ ràng
WHERE (A = 1 OR B = 2) AND C = 3
:::
4. Toán tử đặc biệt
BETWEEN – Trong khoảng
-- Sản phẩm giá từ 10 triệu đến 25 triệu
SELECT TenSP, Gia FROM SanPham
WHERE Gia BETWEEN 10000000 AND 25000000;
-- Đơn hàng trong tháng 12/2024
SELECT * FROM DonHang
WHERE NgayDat BETWEEN '2024-12-01' AND '2024-12-31';
IN – Nằm trong danh sách
-- Sản phẩm thuộc danh mục Điện thoại, Laptop hoặc Máy tính bảng
SELECT TenSP, DanhMuc FROM SanPham
WHERE DanhMuc IN ('Điện thoại', 'Laptop', 'Máy tính bảng');
-- Tương đương với:
-- WHERE DanhMuc = 'Điện thoại' OR DanhMuc = 'Laptop' OR DanhMuc = 'Máy tính bảng'
LIKE – Tìm kiếm theo mẫu
| Ký tự đại diện | Ý nghĩa | Ví dụ |
|---|---|---|
% | Bất kỳ chuỗi ký tự nào (kể cả rỗng) | '%Phone%' → chứa "Phone" |
_ | Đúng 1 ký tự bất kỳ | '_an' → "Van", "Tan" |
-- Tên sản phẩm bắt đầu bằng "iPhone"
SELECT * FROM SanPham WHERE TenSP LIKE 'iPhone%';
-- Tên sản phẩm chứa từ "Pro"
SELECT * FROM SanPham WHERE TenSP LIKE '%Pro%';
-- Tên có đúng 3 ký tự
SELECT * FROM SanPham WHERE TenSP LIKE '___';
-- Email có đuôi gmail
SELECT HoTen, Email FROM KhachHang WHERE Email LIKE '%@gmail.com';
IS NULL / IS NOT NULL – Kiểm tra giá trị NULL
-- Khách hàng chưa có email
SELECT HoTen FROM KhachHang WHERE Email IS NULL;
-- Sản phẩm đã có mô tả
SELECT TenSP FROM SanPham WHERE MoTa IS NOT NULL;
:::info NULL không phải là 0 hay chuỗi rỗng
-- SAI: Không thể so sánh NULL bằng =
WHERE Email = NULL
-- ĐÚNG: Phải dùng IS NULL
WHERE Email IS NULL
:::
5. Sắp xếp kết quả – ORDER BY
Cú pháp
SELECT ... FROM ... ORDER BY cot1 [ASC|DESC], cot2 [ASC|DESC];
ASC(Ascending): Tăng dần (mặc định).DESC(Descending): Giảm dần.
Ví dụ
-- Sắp xếp sản phẩm theo giá tăng dần
SELECT TenSP, Gia FROM SanPham ORDER BY Gia ASC;
-- Sắp xếp theo giá giảm dần
SELECT TenSP, Gia FROM SanPham ORDER BY Gia DESC;
-- Sắp xếp theo danh mục (A-Z), cùng danh mục thì theo giá giảm dần
SELECT TenSP, DanhMuc, Gia FROM SanPham
ORDER BY DanhMuc ASC, Gia DESC;
-- Sắp xếp theo cột tính toán
SELECT TenSP, Gia, SoLuongTon, Gia * SoLuongTon AS GiaTriTonKho
FROM SanPham
ORDER BY GiaTriTonKho DESC;
6. Giới hạn kết quả – LIMIT
Cú pháp
SELECT ... FROM ... LIMIT so_dong;
SELECT ... FROM ... LIMIT vi_tri_bat_dau, so_dong;
Ví dụ
-- Lấy 5 sản phẩm đầu tiên
SELECT * FROM SanPham LIMIT 5;
-- Top 3 sản phẩm đắt nhất
SELECT TenSP, Gia FROM SanPham ORDER BY Gia DESC LIMIT 3;
-- Phân trang: Lấy 10 sản phẩm, bắt đầu từ dòng thứ 11 (trang 2)
SELECT * FROM SanPham LIMIT 10, 10;
-- LIMIT 10, 10 = bỏ qua 10 dòng đầu, lấy 10 dòng tiếp theo
-- Top 5 nhân viên lương cao nhất
SELECT HoTen, Luong FROM NhanVien ORDER BY Luong DESC LIMIT 5;
7. Biểu thức tính toán trong SELECT
-- Tính giá trị tồn kho
SELECT
TenSP,
Gia,
SoLuongTon,
Gia * SoLuongTon AS GiaTriTonKho
FROM SanPham;
-- Tính giá sau giảm 15%
SELECT
TenSP,
Gia AS GiaGoc,
Gia * 0.85 AS GiaSauGiam,
Gia - Gia * 0.85 AS SoTienGiam
FROM SanPham;
-- Hiển thị kèm đơn vị
SELECT
TenSP,
CONCAT(FORMAT(Gia, 0), ' VNĐ') AS GiaBan
FROM SanPham;
8. Thứ tự thực hiện câu lệnh SELECT
SELECT cot1, cot2 -- 5. Chọn cột hiển thị
FROM ten_bang -- 1. Chọn bảng
WHERE dieu_kien -- 2. Lọc dữ liệu
ORDER BY cot1 -- 3. Sắp xếp
LIMIT n; -- 4. Giới hạn kết quả
:::tip Mẹo ghi nhớ thứ tự viết FROM → WHERE → ORDER BY → LIMIT → SELECT
Viết tắt: "Từ Ở Đâu Sắp Lấy Chọn" :::
Bài tập thực hành
Dữ liệu mẫu
CREATE DATABASE IF NOT EXISTS BaiTapSQL;
USE BaiTapSQL;
CREATE TABLE NhanVien (
MaNV INT AUTO_INCREMENT PRIMARY KEY,
HoTen VARCHAR(100) NOT NULL,
PhongBan VARCHAR(50),
ChucVu VARCHAR(50),
Luong DECIMAL(12, 2),
NgayVaoLam DATE,
Email VARCHAR(255)
);
INSERT INTO NhanVien (HoTen, PhongBan, ChucVu, Luong, NgayVaoLam, Email) VALUES
('Nguyễn Văn An', 'Kinh doanh', 'Nhân viên', 12000000, '2022-01-15', 'an@company.com'),
('Trần Thị Bình', 'Kỹ thuật', 'Trưởng nhóm', 20000000, '2020-06-01', 'binh@company.com'),
('Lê Minh Châu', 'Kinh doanh', 'Quản lý', 30000000, '2018-03-10', NULL),
('Phạm Đức Dũng', 'Nhân sự', 'Nhân viên', 11000000, '2023-01-20', 'dung@company.com'),
('Hoàng Thị Em', 'Kỹ thuật', 'Nhân viên', 15000000, '2021-09-01', 'em@company.com'),
('Võ Văn Phong', 'Kinh doanh', 'Nhân viên', 13500000, '2022-07-15', NULL),
('Đặng Thuỳ Giang', 'Nhân sự', 'Trưởng nhóm', 18000000, '2019-11-01', 'giang@company.com'),
('Bùi Quốc Hải', 'Kỹ thuật', 'Nhân viên', 16000000, '2021-04-10', 'hai@company.com'),
('Ngô Thanh Inh', 'Kinh doanh', 'Nhân viên', 12500000, '2023-06-01', 'inh@company.com'),
('Lý Kim Khoa', 'Kỹ thuật', 'Quản lý', 35000000, '2017-01-15', 'khoa@company.com');
Bài tập
- Lấy tất cả thông tin nhân viên.
- Lấy họ tên và lương của nhân viên, đặt alias tiếng Việt.
- Liệt kê các phòng ban (không trùng).
- Nhân viên có lương trên 15 triệu.
- Nhân viên thuộc phòng Kinh doanh hoặc Kỹ thuật.
- Nhân viên vào làm từ năm 2021 đến 2023.
- Nhân viên có tên chứa "Nguyễn".
- Nhân viên chưa có email.
- Top 3 nhân viên lương cao nhất.
- Nhân viên phòng Kỹ thuật, sắp xếp theo lương giảm dần, hiển thị thêm cột Lương sau thuế (trừ 10%).
Quay lại: Roadmap · Bài tiếp: Bài 6 – Hàm Tổng Hợp & GROUP BY