Day 7 - Advanced: UNION & Subqueries
Bối cảnh: Hệ thống E-commerce (Thương mại điện tử) - Tương tự Shopee
1. UNION
UNION: Dùng để kết hợp kết quả từ hai hoặc nhiều truy vấn thành một bảng kết quả duy nhất. Các truy vấn phải có cùng số cột và kiểu dữ liệu.
Lưu ý: UNION tự động loại bỏ các bản ghi trùng lặp. Nếu muốn giữ lại bản ghi trùng lặp, sử dụng UNION ALL.
Ví dụ:
SELECT product_name FROM products WHERE category = 'Electronics' UNION SELECT product_name FROM products WHERE category = 'Clothing';
Câu lệnh này sẽ trả về tên sản phẩm từ hai danh mục "Electronics" và "Clothing".
2. UNION - Practice
Thực hành sử dụng UNION để kết hợp dữ liệu từ hai bảng:
SELECT customer_name FROM customers WHERE city = 'Hanoi' UNION SELECT customer_name FROM customers WHERE city = 'Ho Chi Minh City';
Câu lệnh này sẽ trả về tên khách hàng từ hai thành phố Hà Nội và TP. Hồ Chí Minh.
3. Challenge: UNION
- Yêu cầu: Viết truy vấn để kết hợp danh sách sản phẩm từ hai danh mục "Electronics" và "Home Appliances" từ bảng products.
4. Solution: UNION
Giải pháp:
SELECT product_name FROM products WHERE category = 'Electronics' UNION SELECT product_name FROM products WHERE category = 'Home Appliances';
5. Subqueries in WHERE
Subquery (Truy vấn con): Một truy vấn được lồng bên trong một truy vấn khác.
Subquery trong WHERE: Dùng để lọc dữ liệu dựa trên kết quả của một truy vấn con.
Ví dụ:
SELECT product_name, price FROM products WHERE price > (SELECT AVG(price) FROM products);
Câu lệnh này sẽ trả về các sản phẩm có giá cao hơn giá trung bình của tất cả sản phẩm.
6. Challenge: Subqueries in WHERE
- Yêu cầu: Viết truy vấn để lấy thông tin đơn hàng (order_id, total_amount) từ bảng orders có tổng giá trị lớn hơn giá trị trung bình của tất cả đơn hàng.
7. Solution: Subqueries in WHERE
Giải pháp:
SELECT order_id, total_amount FROM orders WHERE total_amount > (SELECT AVG(total_amount) FROM orders);
8. More challenges: Subqueries in WHERE
- Yêu cầu: Viết truy vấn để lấy thông tin khách hàng (customer_name, email) từ bảng customers có ít nhất một đơn hàng trong bảng orders.
9. Solution: More challenges
Giải pháp:
SELECT customer_name, email FROM customers WHERE customer_id IN (SELECT DISTINCT customer_id FROM orders);
10. Subqueries in FROM
Subquery trong FROM: Dùng để tạo một bảng tạm thời từ kết quả của một truy vấn con.
Ví dụ:
SELECT category, AVG(price) AS avg_price FROM (SELECT category, price FROM products) AS temp_table GROUP BY category;
Câu lệnh này sẽ trả về giá trung bình của các sản phẩm theo từng danh mục.
11. Challenge: Subqueries in FROM
- Yêu cầu: Viết truy vấn để tính tổng giá trị đơn hàng (total_amount) theo từng khách hàng (customer_id) từ bảng orders.
12. Solution: Subqueries in FROM
Giải pháp:
SELECT customer_id, SUM(total_amount) AS total_spent FROM (SELECT customer_id, total_amount FROM orders) AS temp_table GROUP BY customer_id;
13. Subqueries in SELECT
Subquery trong SELECT: Dùng để tính toán giá trị trong một cột dựa trên kết quả của một truy vấn con.
Ví dụ:
SELECT customer_name, (SELECT COUNT(*) FROM orders WHERE orders.customer_id = customers.customer_id) AS order_count FROM customers;
Câu lệnh này sẽ trả về tên khách hàng và số lượng đơn hàng của họ.
14. Challenge: Subqueries in SELECT
- Yêu cầu: Viết truy vấn để lấy tên sản phẩm (product_name) và số lượng đơn hàng (order_count) của mỗi sản phẩm từ bảng products và orders.
15. Solution: Subqueries in SELECT
Giải pháp:
SELECT product_name, (SELECT COUNT(*) FROM orders WHERE orders.product_id = products.product_id) AS order_count FROM products;
16. Correlated Subqueries in WHERE
Correlated Subquery (Truy vấn con tương quan): Một truy vấn con tham chiếu đến các cột của truy vấn bên ngoài.
Ví dụ:
SELECT product_name, price FROM products p1 WHERE price > (SELECT AVG(price) FROM products p2 WHERE p2.category = p1.category);
Câu lệnh này sẽ trả về các sản phẩm có giá cao hơn giá trung bình của danh mục tương ứng.
17. Challenge: Correlated subqueries in WHERE
- Yêu cầu: Viết truy vấn để lấy thông tin đơn hàng (order_id, total_amount) từ bảng orders có tổng giá trị lớn hơn giá trị trung bình của các đơn hàng cùng phương thức thanh toán (payment_method).
18. Solution: Correlated subqueries in WHERE
Giải pháp:
SELECT order_id, total_amount FROM orders o1 WHERE total_amount > (SELECT AVG(total_amount) FROM orders o2 WHERE o2.payment_method = o1.payment_method);
19. Correlated Subquery in SELECT
Correlated Subquery trong SELECT: Dùng để tính toán giá trị trong một cột dựa trên kết quả của một truy vấn con tương quan.
Ví dụ:
SELECT customer_name, (SELECT SUM(total_amount) FROM orders WHERE orders.customer_id = customers.customer_id) AS total_spent FROM customers;
Câu lệnh này sẽ trả về tên khách hàng và tổng giá trị đơn hàng của họ.
20. More challenges: Correlated subqueries
- Yêu cầu: Viết truy vấn để lấy tên sản phẩm (product_name) và tổng số lượng đã bán (total_quantity) từ bảng products và orders.
21. Solution: More challenges
Giải pháp:
SELECT product_name, (SELECT SUM(quantity) FROM orders WHERE orders.product_id = products.product_id) AS total_quantity FROM products;
22. Today's slides
Tổng kết lại các kiến thức về UNION và Subqueries đã học trong ngày hôm nay.
Cung cấp slide tham khảo để bạn ôn tập và thực hành thêm.
23. Today's summary
Hôm nay, bạn đã học:
Cách sử dụng UNION và UNION ALL để kết hợp dữ liệu từ nhiều truy vấn.
Cách sử dụng Subqueries trong WHERE, FROM, và SELECT.
Cách sử dụng Correlated Subqueries để thực hiện các phép tính phức tạp.
Hẹn gặp lại bạn vào ngày 8 với chủ đề Advanced: Course project!
24. Today's challenges
Thử thách 1: Viết truy vấn để lấy danh sách khách hàng (customer_name) và tổng giá trị đơn hàng (total_spent) của họ từ bảng customers và orders.
Thử thách 2: Viết truy vấn để lấy tên sản phẩm (product_name) và số lượng đơn hàng (order_count) của mỗi sản phẩm từ bảng products và orders.
Thử thách 3: Viết truy vấn để lấy thông tin đơn hàng (order_id, total_amount) có tổng giá trị lớn hơn giá trị trung bình của các đơn hàng cùng phương thức thanh toán (payment_method).