Chuyển tới nội dung chính

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ĩaVí dụ
=BằngWHERE DanhMuc = 'Điện thoại'
!= hoặc <>KhácWHERE TrangThai != 'Đã huỷ'
>Lớn hơnWHERE Gia > 10000000
<Nhỏ hơnWHERE SoLuongTon < 10
>=Lớn hơn hoặc bằngWHERE DiemTB >= 8
<=Nhỏ hơn hoặc bằngWHERE 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ĩaVí 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

  1. Lấy tất cả thông tin nhân viên.
  2. Lấy họ tênlương của nhân viên, đặt alias tiếng Việt.
  3. Liệt kê các phòng ban (không trùng).
  4. Nhân viên có lương trên 15 triệu.
  5. Nhân viên thuộc phòng Kinh doanh hoặc Kỹ thuật.
  6. Nhân viên vào làm từ năm 2021 đến 2023.
  7. Nhân viên có tên chứa "Nguyễn".
  8. Nhân viên chưa có email.
  9. Top 3 nhân viên lương cao nhất.
  10. 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