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 orderscustomers 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 employeesoffices
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)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 employeescustomersordersorderdetails, rồi SUMGROUP 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 BYLIMIT 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ì?”

 

 

 

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *