Bài 1: Giới thiệu về Trình quản lý quảng cáo
🎓 Bài thực hành SQL – Truy vấn nhiều bảng trong hệ thống khóa học
💡 Mục tiêu bài học
-
Kết hợp nhiều bảng bằng
JOIN -
Sử dụng truy vấn con trong
SELECT,WHEREvàFROM -
Ứng dụng
GROUP BYđể tổng hợp dữ liệu
🧩 Các bảng liên quan
| Bảng | Mục đích |
|---|---|
KhoaHoc |
Chứa thông tin khóa học |
ChuDe |
Danh sách chủ đề của khóa học |
Video |
Danh sách video thuộc mỗi khóa học |
DangKyKhoaHoc |
Thông tin học viên đăng ký khóa học |
🧩 Bổ sung bảng :
| DangKyKhoaHoc | |
| #ID | int |
| idHocVien | int |
| idKhoaHoc | int |
| ThoiGianDangKy | datetime |
| HocPhi | float |
| idNhanVienXacNhan | int |
| ThoiGianXacNhan | datetime |
THỰC HÀNH
1. Lấy danh sách học viên đã đăng ký và thông tin khóa học tương ứng
SELECT
dkh.idHocVien,
kh.TenKhoaHoc,
dkh.ThoiGianDangKy,
dkh.HocPhi
FROM DangKyKhoaHoc dkh
JOIN KhoaHoc kh ON dkh.idKhoaHoc = kh.ID;
📌 Giải thích: Dùng JOIN để lấy tên khóa học từ bảng KhoaHoc, liên kết qua idKhoaHoc.
2. Lấy danh sách tất cả khóa học và tổng số lượt đăng ký
SELECT
kh.TenKhoaHoc,
COUNT(dkh.ID) AS SoLuotDangKy
FROM KhoaHoc kh
LEFT JOIN DangKyKhoaHoc dkh ON kh.ID = dkh.idKhoaHoc
GROUP BY kh.TenKhoaHoc;
📌 Giải thích:
-
Dùng
LEFT JOINđể vẫn hiển thị các khóa học chưa có lượt đăng ký. -
GROUP BYđể tính tổng lượt đăng ký theo khóa.
3. Truy vấn con trong SELECT: Tổng học phí từng học viên đã đóng
SELECT
idHocVien,
(SELECT SUM(HocPhi)
FROM DangKyKhoaHoc dkh2
WHERE dkh2.idHocVien = dkh1.idHocVien
) AS TongTienDaDong
FROM DangKyKhoaHoc dkh1
GROUP BY idHocVien;
📌 Giải thích: Dùng truy vấn con để tính tổng học phí của mỗi học viên.
4. Truy vấn con trong WHERE: Lọc ra các đăng ký có học phí cao hơn trung bình
SELECT *
FROM DangKyKhoaHoc
WHERE HocPhi > (
SELECT AVG(HocPhi) FROM DangKyKhoaHoc
);
📌 Giải thích: Truy vấn con trong WHERE giúp lọc dữ liệu nâng cao.
5. Truy vấn con trong FROM: Tổng số lượt đăng ký theo chủ đề
SELECT
cd.TenChuDe,
COUNT(dkh.ID) AS TongDangKy
FROM (
SELECT kh.idChuDe, dkh.ID
FROM KhoaHoc kh
JOIN DangKyKhoaHoc dkh ON kh.ID = dkh.idKhoaHoc
) AS Sub
JOIN ChuDe cd ON cd.ID = Sub.idChuDe
GROUP BY cd.TenChuDe;
📌 Giải thích:
-
Truy vấn con trong
FROMtách phần trung gian (lượt đăng ký theoidChuDe) -
Kết hợp với
ChuDeđể nhóm theo tên chủ đề.
Luyện tập truy vấn nâng cao với JOIN và Subquery – Ứng dụng quản lý cửa hàng cho thuê xe
1. Mô tả bài toán thực tế
Một cửa hàng cho thuê xe máy cần quản lý:
- Xe máy: Trạng thái (có sẵn, đang thuê), giá thuê theo giờ.
- Khách hàng: Ai đang thuê xe, có phải thành viên không.
- Hợp đồng thuê: Ngày thuê, ngày trả, tổng tiền thuê.
Hệ thống sử dụng các bảng sau:
CREATE TABLE Xe (
ID INT PRIMARY KEY IDENTITY(1,1),
BienSo VARCHAR(15) UNIQUE NOT NULL,
LoaiXe NVARCHAR(100) NOT NULL,
TrangThai NVARCHAR(50) CHECK (TrangThai IN ('Có sẵn', 'Đang thuê')),
GiaTheoGio DECIMAL(10,2) NOT NULL
);
CREATE TABLE KhachHang (
ID INT PRIMARY KEY IDENTITY(1,1),
HoTen NVARCHAR(100) NOT NULL,
SoDienThoai VARCHAR(15) UNIQUE NOT NULL,
LoaiKhachHang NVARCHAR(50) CHECK (LoaiKhachHang IN ('Thành viên', 'Vãng lai'))
);
CREATE TABLE HopDongThue (
ID INT PRIMARY KEY IDENTITY(1,1),
IDXe INT FOREIGN KEY REFERENCES Xe(ID),
IDKhachHang INT FOREIGN KEY REFERENCES KhachHang(ID),
NgayThue DATETIME NOT NULL,
NgayTra DATETIME NULL,
TongTien DECIMAL(10,2) NULL
);
DỮ LIỆU MẪU:
INSERT INTO Xe (BienSo, LoaiXe, TrangThai, GiaTheoGio) VALUES
('51A-12345', 'Honda Air Blade', 'Có sẵn', 50000),
('59X-67890', 'Yamaha Exciter', 'Đang thuê', 60000),
('30H-11111', 'Suzuki Raider', 'Có sẵn', 55000),
('79D-22222', 'Honda Vision', 'Đang thuê', 45000),
('43C-33333', 'Yamaha Janus', 'Có sẵn', 40000);
INSERT INTO KhachHang (HoTen, SoDienThoai, LoaiKhachHang) VALUES
('Nguyễn Văn A', '0912345678', 'Thành viên'),
('Trần Thị B', '0987654321', 'Vãng lai'),
('Lê Văn C', '0909123456', 'Thành viên'),
('Phạm Thị D', '0978563412', 'Vãng lai'),
('Hoàng Minh E', '0923456789', 'Thành viên');
INSERT INTO HopDongThue (IDXe, IDKhachHang, NgayThue, NgayTra, TongTien) VALUES
(2, 1, '2024-07-01 08:00:00', '2024-07-01 12:00:00', NULL), -- Đã trả xe, cần tính tiền
(4, 2, '2024-07-02 14:00:00', NULL, NULL), -- Chưa trả xe
(2, 3, '2024-07-03 09:30:00', '2024-07-03 11:30:00', NULL), -- Đã trả xe, cần tính tiền
(1, 4, '2024-07-04 07:00:00', NULL, NULL), -- Chưa trả xe
(5, 5, '2024-07-05 10:00:00', '2024-07-05 13:00:00', NULL); -- Đã trả xe, cần tính tiền