Truy vấn trên một bảng là nền tảng thiết yếu khi làm việc với MySQL. Các thao tác này không thay đổi dữ liệu gốc mà chỉ định dạng, lọc và tổng hợp kết quả theo yêu cầu.
Chuẩn bị dữ liệu mẫu
Tạo bảng staff mô phỏng nhân sự trong doanh nghiệp:
CREATE TABLE staff (
id INT PRIMARY KEY AUTO_INCREMENT,
full_name VARCHAR(30) NOT NULL,
gender ENUM('M', 'F') DEFAULT 'M',
age TINYINT UNSIGNED,
hire_date DATE,
role VARCHAR(40),
department_id TINYINT,
base_salary DECIMAL(12,2),
office_no SMALLINT
);
INSERT INTO staff (full_name, gender, age, hire_date, role, department_id, base_salary, office_no) VALUES
('Lý Văn Châu', 'M', 28, '2012-11-01', 'Giáo viên', 1, 2100.00, 401),
('Ngô Bội Kỳ', 'M', 81, '2013-03-05', 'Giáo viên', 1, 8300.00, 401),
('Dương Thiên Bảo', 'M', 78, '2015-03-02', 'Giáo viên', 1, 1000000.31, 401),
('Viên Hạo', 'M', 73, '2014-07-01', 'Giáo viên', 1, 3500.00, 401),
('Tinh Lệ Dương', 'F', 18, '2011-02-11', 'Giáo viên', 1, 9000.00, 401),
('Thành Long', 'M', 48, '2010-11-11', 'Giáo viên', 1, 10000.00, 401),
('Gia Cát Lượng', 'M', 18, '1900-03-01', 'Giáo viên', 1, 30000.00, 401),
('Ngô Ngạn Tổ', 'M', 18, '2017-03-01', 'Cố vấn', 1, 7300.33, 401),
('Lưu Tiểu Linh', 'F', 48, '2015-03-11', 'Nhân viên bán hàng', 2, 3000.13, 402),
('Tiểu Yến', 'F', 38, '2010-11-01', 'Nhân viên bán hàng', 2, 2000.35, 402),
('Đinh Đinh', 'F', 18, '2011-03-12', 'Nhân viên bán hàng', 2, 1000.37, 402),
('Tinh Tinh', 'F', 18, '2016-05-13', 'Nhân viên bán hàng', 2, 3000.29, 402),
('Cát Cát', 'F', 28, '2017-01-27', 'Nhân viên bán hàng', 2, 4000.33, 402),
('Trương Dã', 'M', 28, '2016-03-11', 'Nhân viên vận hành', 3, 10000.13, 403),
('Thành Diệu Kim', 'M', 18, '1997-03-12', 'Nhân viên vận hành', 3, 20000.00, 403),
('Thành Diệu Ngân', 'F', 18, '2013-03-11', 'Nhân viên vận hành', 3, 19000.00, 403),
('Thành Diệu Đồng', 'M', 18, '2015-04-11', 'Nhân viên vận hành', 3, 18000.00, 403),
('Thành Diệu Thiết', 'F', 18, '2014-05-12', 'Nhân viên vận hành', 3, 17000.00, 403);
Các kiểu truy vấn cơ bản
- Lấy cột cụ thể:
SELECT full_name, base_salary FROM staff; - Lấy toàn bộ cột:
SELECT * FROM staff; - Loại bỏ trùng lặp:
SELECT DISTINCT role FROM staff; - Tính toán tại thời điểm truy vấn:
SELECT full_name, base_salary * 12 AS annual_income FROM staff; - Ghép chuỗi với
CONCAT:SELECT CONCAT('Nhân viên: ', full_name, ' — Lương năm: ', base_salary * 12) AS summary FROM staff; - Dùng
CONCAT_WSvới dấu phân cách:SELECT CONCAT_WS(' | ', full_name, role, base_salary) AS profile FROM staff; - Điều kiện động với
CASE:SELECT full_name, CASE WHEN role = 'Giáo viên' THEN 'Giảng dạy' WHEN role = 'Nhân viên vận hành' THEN 'Hỗ trợ kỹ thuật' ELSE 'Khác' END AS category FROM staff;
Bộ lọc điều kiện
- Toán tử so sánh:
=,<>,>,<=, v.v. - Phạm vi giá trị:
SELECT * FROM staff WHERE base_salary BETWEEN 10000 AND 20000; - Chọn nhiều giá trị:
SELECT * FROM staff WHERE role IN ('Giáo viên', 'Nhân viên vận hành'); - Tìm kiếm mẫu:
SELECT * FROM staff WHERE full_name LIKE 'Thành%';(%: bất kỳ số ký tự nào,_: đúng một ký tự) - Toán tử logic:
SELECT * FROM staff WHERE role = 'Nhân viên vận hành' AND full_name REGEXP '^Thành.*';SELECT * FROM staff WHERE base_salary = 20000 OR base_salary = 30000;SELECT * FROM staff WHERE full_name NOT IN ('Thành Diệu Kim', 'Thành Diệu Ngân');
- Xử lý giá trị NULL:
SELECT * FROM staff WHERE role IS NOT NULL; - Biểu thức chính quy:
SELECT * FROM staff WHERE full_name REGEXP '^[LNT].{2,4}';
Nhóm hóa và tổng hợp
Khi dùng GROUP BY, các hàm tổng hợp (aggregate) cho phép tính toán trên từng nhóm:
- Số lượng bản ghi:
SELECT role, COUNT(*) AS member_count FROM staff GROUP BY role; - Giá trị cực trị:
SELECT role, MAX(base_salary), MIN(base_salary) FROM staff GROUP BY role; - Giá trị trung bình & tổng:
SELECT department_id, AVG(base_salary), SUM(base_salary) FROM staff GROUP BY department_id; - Ghép tên thành danh sách:
SELECT role, GROUP_CONCAT(full_name ORDER BY age SEPARATOR '; ') AS names FROM staff GROUP BY role;
Lọc sau nhóm hóa: HAVING
HAVING hoạt động sau GROUP BY, hỗ trợ điều kiện dựa trên kết quả tổng hợp:
SELECT role, COUNT(*) FROM staff GROUP BY role HAVING COUNT(*) > 4;— Chỉ hiện thị vai trò có từ 5 người trở lên.SELECT role, AVG(base_salary) FROM staff GROUP BY role HAVING AVG(base_salary) > 5000;
Sắp xếp và giới hạn kết quả
- Sắp xếp tăng dần (mặc định):
SELECT full_name, age FROM staff ORDER BY age; - Sắp xếp giảm dần:
SELECT full_name, base_salary FROM staff ORDER BY base_salary DESC; - Sắp xếp đa mức:
SELECT full_name, age, base_salary FROM staff ORDER BY age ASC, base_salary DESC; - Giới hạn số bản ghi:
- Lấy top 3 lương cao nhất:
SELECT full_name, base_salary FROM staff ORDER BY base_salary DESC LIMIT 3; - Phân trang (mỗi trang 5 dòng):
Trang 1:SELECT * FROM staff ORDER BY id LIMIT 5;
Trang 2:SELECT * FROM staff ORDER BY id LIMIT 5 OFFSET 5;
Trang 3:SELECT * FROM staff ORDER BY id LIMIT 5 OFFSET 10;
- Lấy top 3 lương cao nhất: