-
Giới thiệu và khởi tạo môi trường MySQL
- Hướng dẫn cài đặt và cấu hình MySQL Server trên Windows cho kết nối từ xa
- Vận dụng tư duy phân tích dữ liệu với Mysql từ cơ bản đến nâng cao
- Vận dụng tư duy phân tích quản trị dữ liệu với MySQL
- Tối ưu hoá công việc quản trị với view và bảng tạm
- Tôi ưu hoá với thủ tục – procedure trong mysql
- Nhóm hàm windown
- Con trỏ và phân vùng trong mysql
- Làm việc với hàm tự tạo trong Mysql
- Làm việc với trigger trong Mysql
- Làm việc với giao dịch
- Tìm hiểu về truy vấn động
- Even – Sự kiện định kỳ trong Mysql
-
Quản trị dữ liệu trong doanh nghiệp
- Tổng quan về trục quản trị dữ liệu
- Quản trị & Giám sát hệ thống với cơ sở dữ liệu ảo information_schema
- Cấu hình và lưu trữ
- Cấu hình file my.ini
- An toàn và toàn vẹn dữ liệu – Bảo mật – Backup
- Hiệu năng và tối ưu hoá
- Đồng bộ và phục hồi
- Phân tích tối ưu hoá hiệu năng với dữ liệu bảng performance_schema
-
Chiến lược quản trị dữ liệu
Vận dụng tư duy phân tích dữ liệu với Mysql từ cơ bản đến nâng cao
BỘ BÀI TẬP SQL – DỰA TRÊN MÔ HÌNH BÁN HÀNG

🧩 CHỦ ĐỀ 1 – TRUY VẤN CƠ BẢN (SELECT, WHERE, ORDER BY, LIMIT)
Mục tiêu: làm quen với việc chọn, lọc, sắp xếp dữ liệu.
| # | Yêu cầu | Giải thích & Gợi ý truy vấn |
|---|---|---|
| 1 | Liệt kê tất cả sản phẩm có trong bảng products |
Giúp hiểu SELECT * FROM products; |
| 2 | Hiển thị tên, mã và giá bán (productName, productCode, buyPrice) của sản phẩm có buyPrice > 100 |
Giới thiệu WHERE điều kiện lọc |
| 3 | Tìm 10 sản phẩm có giá cao nhất | Dùng ORDER BY buyPrice DESC LIMIT 10 |
| 4 | Liệt kê tên và mô tả của các dòng sản phẩm (productlines) |
Truy vấn cột cụ thể, không cần * |
| 5 | Tìm tất cả khách hàng ở quốc gia “USA” | SELECT customerName FROM customers WHERE country = 'USA'; |
| 6 | Hiển thị tất cả nhân viên làm việc ở văn phòng có mã officeCode = 1 |
Giúp hiểu khóa ngoại officeCode |
| 7 | Đếm số lượng sản phẩm trong từng dòng sản phẩm | Giới thiệu GROUP BY productLine |
🧠 CHỦ ĐỀ 2 – TRUY VẤN TRUNG BÌNH (JOIN, ALIAS, GROUP BY, HAVING)
Mục tiêu: hiểu cách liên kết bảng, tổng hợp và nhóm dữ liệu.
| # | Yêu cầu | Giải thích & Gợi ý |
|---|---|---|
| 1 | Liệt kê danh sách đơn hàng cùng tên khách hàng đặt hàng đó | JOIN orders và customers qua customerNumber |
| 2 | Hiển thị thông tin nhân viên cùng văn phòng họ làm việc | JOIN employees và offices |
| 3 | Liệt kê mã đơn hàng, ngày đặt và tổng số sản phẩm trong từng đơn | JOIN orderdetails, GROUP BY orderNumber |
| 4 | Tính tổng doanh thu (SUM(quantityOrdered * priceEach)) theo từng khách hàng |
Dùng JOIN 3 bảng: orders, orderdetails, customers |
| 5 | Tính trung bình giá mua sản phẩm theo dòng sản phẩm | AVG(buyPrice) và GROUP BY productLine |
| 6 | Tìm khách hàng có tổng doanh thu lớn hơn 50,000 | Dùng HAVING SUM(...) > 50000 |
| 7 | Liệt kê khách hàng và nhân viên bán hàng (qua salesRepEmployeeNumber) |
Dùng LEFT JOIN để thể hiện khách hàng chưa có nhân viên phụ trách |
📊 CHỦ ĐỀ 3 – TRUY VẤN NÂNG CAO (SUBQUERY, CASE, DATE, WINDOW)
Mục tiêu: khai thác dữ liệu mang tính phân tích & so sánh.
| # | Yêu cầu | Giải thích & Gợi ý |
|---|---|---|
| 1 | Tìm sản phẩm có giá cao hơn mức trung bình toàn bộ sản phẩm | Subquery: WHERE buyPrice > (SELECT AVG(buyPrice) FROM products) |
| 2 | Liệt kê khách hàng có tổng thanh toán cao nhất | Subquery kết hợp payments + GROUP BY customerNumber |
| 3 | Tính tổng số đơn hàng của mỗi tháng trong năm 2024 | Dùng MONTH(orderDate) + GROUP BY |
| 4 | Phân loại sản phẩm thành “Giá cao”, “Trung bình”, “Thấp” | Dùng CASE WHEN buyPrice > 100 THEN 'Cao' ... END |
| 5 | Tìm đơn hàng chưa được giao (shippedDate IS NULL) |
Lọc điều kiện NULL |
| 6 | Tính thứ hạng (RANK()) khách hàng theo tổng doanh thu |
Dùng window function RANK() OVER (ORDER BY SUM(...) DESC) |
| 7 | Liệt kê khách hàng có ít nhất 3 đơn hàng | Dùng HAVING COUNT(orderNumber) >= 3 |
📈 CHỦ ĐỀ 4 – PHÂN TÍCH KINH DOANH (BUSINESS ANALYTICS)
Mục tiêu: ứng dụng SQL để ra quyết định kinh doanh và phân tích dữ liệu.
| # | Bài tập | Gợi ý hướng phân tích |
|---|---|---|
| 1 | Doanh thu trung bình của mỗi nhân viên bán hàng | JOIN employees – customers – orders – orderdetails, rồi SUM và GROUP BY employeeNumber |
| 2 | 3 dòng sản phẩm mang lại doanh thu cao nhất | Tính doanh thu theo productLine, ORDER BY và LIMIT 3 |
| 3 | Tỷ lệ khách hàng thanh toán trễ (so sánh paymentDate với shippedDate) |
Dùng CASE WHEN paymentDate > shippedDate THEN 1 ELSE 0 END |
| 4 | Phân tích doanh thu theo quốc gia | GROUP BY country |
| 5 | Tìm quốc gia có doanh thu cao nhất | Dùng ORDER BY SUM(amount) DESC LIMIT 1 |
| 6 | Xác định top 5 khách hàng lớn nhất trong 6 tháng gần nhất | Dùng WHERE paymentDate >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH) |
| 7 | So sánh số đơn hàng mỗi quý trong năm | QUARTER(orderDate) + GROUP BY |
🎓 BỘ ĐÁP ÁN & GIẢI THÍCH – SQL PHÂN TÍCH DỮ LIỆU (MÔ HÌNH BÁN HÀNG)
🧩 CHỦ ĐỀ 1 – TRUY VẤN CƠ BẢN
| # | Câu hỏi | Câu lệnh SQL | Giải thích |
|---|---|---|---|
| 1 | Liệt kê tất cả sản phẩm | SELECT * FROM products; |
Lấy toàn bộ dữ liệu, giúp hiểu cấu trúc bảng |
| 2 | Hiển thị productName, productCode, buyPrice với giá > 100 |
SELECT productName, productCode, buyPrice FROM products WHERE buyPrice > 100; |
Dùng WHERE để lọc dữ liệu |
| 3 | Tìm 10 sản phẩm có giá cao nhất | SELECT productName, buyPrice FROM products ORDER BY buyPrice DESC LIMIT 10; |
ORDER BY sắp giảm dần, LIMIT giới hạn kết quả |
| 4 | Liệt kê tên và mô tả của dòng sản phẩm | SELECT productLine, textDescription FROM productlines; |
Cấu trúc truy vấn đơn giản, chọn cột cụ thể |
| 5 | Tìm khách hàng ở “USA” | SELECT customerName, city FROM customers WHERE country = 'USA'; |
Lọc theo quốc gia |
| 6 | Nhân viên làm việc tại officeCode = 1 | SELECT firstName, lastName, jobTitle FROM employees WHERE officeCode = 1; |
Lọc bằng điều kiện cụ thể |
| 7 | Đếm sản phẩm trong từng dòng sản phẩm | SELECT productLine, COUNT(*) AS totalProducts FROM products GROUP BY productLine; |
GROUP BY tổng hợp theo nhóm logic |
🧠 CHỦ ĐỀ 2 – TRUNG CẤP (JOIN, GROUP BY, HAVING)
| # | Câu hỏi | Câu lệnh SQL | Giải thích |
|---|---|---|---|
| 1 | Đơn hàng và tên khách hàng | SELECT o.orderNumber, o.orderDate, c.customerName FROM orders o JOIN customers c ON o.customerNumber = c.customerNumber; |
JOIN để liên kết 2 bảng có khóa ngoại |
| 2 | Nhân viên và văn phòng | SELECT e.firstName, e.lastName, o.city, o.country FROM employees e JOIN offices o ON e.officeCode = o.officeCode; |
Thể hiện quan hệ 1-nhiều |
| 3 | Tổng số sản phẩm mỗi đơn hàng | SELECT orderNumber, SUM(quantityOrdered) AS totalItems FROM orderdetails GROUP BY orderNumber; |
Tổng hợp theo đơn hàng |
| 4 | Doanh thu theo khách hàng | SELECT c.customerName, SUM(od.quantityOrdered * od.priceEach) AS totalRevenue FROM customers c JOIN orders o ON c.customerNumber = o.customerNumber JOIN orderdetails od ON o.orderNumber = od.orderNumber GROUP BY c.customerName; |
Kết hợp 3 bảng và tính doanh thu |
| 5 | Trung bình giá mua theo dòng sản phẩm | SELECT productLine, AVG(buyPrice) AS avgPrice FROM products GROUP BY productLine; |
Tính giá trung bình theo nhóm |
| 6 | Khách hàng doanh thu > 50,000 | SELECT c.customerName, SUM(od.quantityOrdered * od.priceEach) AS totalRevenue FROM customers c JOIN orders o ON c.customerNumber = o.customerNumber JOIN orderdetails od ON o.orderNumber = od.orderNumber GROUP BY c.customerName HAVING totalRevenue > 50000; |
HAVING lọc sau khi nhóm |
| 7 | Khách hàng và nhân viên phụ trách | SELECT c.customerName, e.firstName, e.lastName FROM customers c LEFT JOIN employees e ON c.salesRepEmployeeNumber = e.employeeNumber; |
Dùng LEFT JOIN để không mất khách hàng chưa có salesRep |
📊 CHỦ ĐỀ 3 – NÂNG CAO (SUBQUERY, CASE, DATE, WINDOW)
| # | Câu hỏi | SQL | Giải thích |
|---|---|---|---|
| 1 | Sản phẩm có giá cao hơn trung bình | SELECT productName, buyPrice FROM products WHERE buyPrice > (SELECT AVG(buyPrice) FROM products); |
Subquery so sánh từng hàng với giá trung bình |
| 2 | Khách hàng có tổng thanh toán cao nhất | SELECT customerNumber, SUM(amount) AS totalPay FROM payments GROUP BY customerNumber ORDER BY totalPay DESC LIMIT 1; |
Tổng hợp + xếp hạng bằng ORDER BY |
| 3 | Tổng số đơn hàng mỗi tháng năm 2024 | SELECT MONTH(orderDate) AS month, COUNT(*) AS totalOrders FROM orders WHERE YEAR(orderDate) = 2024 GROUP BY MONTH(orderDate); |
Dùng hàm thời gian |
| 4 | Phân loại sản phẩm theo giá | SELECT productName, buyPrice, CASE WHEN buyPrice > 100 THEN 'Cao' WHEN buyPrice BETWEEN 50 AND 100 THEN 'Trung bình' ELSE 'Thấp' END AS priceCategory FROM products; |
CASE WHEN dùng để gán nhãn dữ liệu |
| 5 | Đơn hàng chưa giao | SELECT orderNumber, orderDate, status FROM orders WHERE shippedDate IS NULL; |
Lọc theo giá trị NULL |
| 6 | Thứ hạng khách hàng theo doanh thu | sql SELECT c.customerName, SUM(od.quantityOrdered * od.priceEach) AS revenue, RANK() OVER (ORDER BY SUM(od.quantityOrdered * od.priceEach) DESC) AS rank_order FROM customers c JOIN orders o ON c.customerNumber = o.customerNumber JOIN orderdetails od ON o.orderNumber = od.orderNumber GROUP BY c.customerName; |
RANK() tính xếp hạng mà không mất dữ liệu |
| 7 | Khách hàng có ≥ 3 đơn hàng | SELECT c.customerName, COUNT(o.orderNumber) AS totalOrders FROM customers c JOIN orders o ON c.customerNumber = o.customerNumber GROUP BY c.customerName HAVING totalOrders >= 3; |
Đếm theo nhóm khách hàng |
📈 CHỦ ĐỀ 4 – PHÂN TÍCH KINH DOANH
| # | Câu hỏi | SQL | Giải thích |
|---|---|---|---|
| 1 | Doanh thu trung bình của mỗi nhân viên bán hàng | sql SELECT e.employeeNumber, e.firstName, e.lastName, ROUND(AVG(od.quantityOrdered * od.priceEach), 2) AS avgRevenue FROM employees e JOIN customers c ON e.employeeNumber = c.salesRepEmployeeNumber JOIN orders o ON c.customerNumber = o.customerNumber JOIN orderdetails od ON o.orderNumber = od.orderNumber GROUP BY e.employeeNumber; |
Kết nối 4 bảng để phân tích hiệu suất nhân viên |
| 2 | 3 dòng sản phẩm doanh thu cao nhất | sql SELECT pl.productLine, SUM(od.quantityOrdered * od.priceEach) AS revenue FROM productlines pl JOIN products p ON pl.productLine = p.productLine JOIN orderdetails od ON p.productCode = od.productCode GROUP BY pl.productLine ORDER BY revenue DESC LIMIT 3; |
Tổng hợp doanh thu theo productLine |
| 3 | Tỷ lệ khách hàng thanh toán trễ | sql SELECT ROUND(SUM(CASE WHEN p.paymentDate > o.shippedDate THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS lateRatePercent FROM orders o JOIN payments p ON o.customerNumber = p.customerNumber; |
Dùng CASE để đếm tỷ lệ vi phạm thời gian |
| 4 | Doanh thu theo quốc gia | sql SELECT c.country, SUM(od.quantityOrdered * od.priceEach) AS totalRevenue FROM customers c JOIN orders o ON c.customerNumber = o.customerNumber JOIN orderdetails od ON o.orderNumber = od.orderNumber GROUP BY c.country ORDER BY totalRevenue DESC; |
Phân tích doanh thu theo thị trường |
| 5 | Quốc gia doanh thu cao nhất | Thêm LIMIT 1 vào câu trên |
Xác định thị trường mạnh nhất |
| 6 | Top 5 khách hàng 6 tháng gần nhất | sql SELECT c.customerName, SUM(p.amount) AS totalAmount FROM customers c JOIN payments p ON c.customerNumber = p.customerNumber WHERE p.paymentDate >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH) GROUP BY c.customerName ORDER BY totalAmount DESC LIMIT 5; |
Lọc thời gian gần nhất, sắp xếp và giới hạn |
| 7 | So sánh số đơn hàng mỗi quý | sql SELECT QUARTER(orderDate) AS quarter, COUNT(orderNumber) AS totalOrders FROM orders GROUP BY QUARTER(orderDate) ORDER BY quarter; |
Dùng QUARTER() để phân tích theo quý |
🧠 Nhận xét tổng thể
- Bộ này bao quát toàn bộ năng lực truy vấn dữ liệu: từ thao tác CRUD → tổng hợp → phân tích logic → xếp hạng.
- Mỗi câu SQL tương ứng một mẫu tư duy phân tích (filter, join, aggregate, rank, label…).
- Chạy từng câu và diễn giải bằng tiếng tự nhiên: “Câu này trả lời câu hỏi kinh doanh gì?”