Bài tập & đáp án
Đề bài đọc tự do. Phần đáp án và giải thích chi tiết chỉ dành cho sinh viên đang học lớp thực hành IT004, cần mã truy cập từ giảng viên.
ĐỀ BÀI
Quản lý bán hàng - Câu 26 ➜ 53
Theo tài liệu hướng dẫn Tuần 3, sử dụng Microsoft SQL Server để thực hiện Phần III - Câu 26 đến câu 53. Tự làm trước khi xem gợi ý/đáp án. Đề bài chi tiết trong file PDF bên dưới.
<MSSV>_<HoVaTen>_BTTH3.sql (MSSV là mã số sinh viên, HoVaTen là họ và tên).- Tìm số hóa đơn đã mua tất cả các sản phẩm do Singapore sản xuất.
- Tìm số hóa đơn trong năm 2006 đã mua tất cả các sản phẩm do Singapore sản xuất.
- Có bao nhiêu hóa đơn không phải của khách hàng đăng ký thành viên mua?
- Có bao nhiêu sản phẩm khác nhau được bán ra trong năm 2006.
- Cho biết trị giá hóa đơn cao nhất, thấp nhất là bao nhiêu?
- Trị giá trung bình của tất cả các hóa đơn được bán ra trong năm 2006 là bao nhiêu?
- Tính doanh thu bán hàng trong năm 2006.
- Tìm số hóa đơn có trị giá cao nhất trong năm 2006.
- Tìm họ tên khách hàng đã mua hóa đơn có trị giá cao nhất trong năm 2006.
- In ra danh sách 3 khách hàng đầu tiên (MAKH, HOTEN) sắp xếp theo doanh số giảm dần.
- In ra danh sách các sản phẩm (MASP, TENSP) có giá bán bằng 1 trong 3 mức giá cao nhất.
- In ra danh sách các sản phẩm (MASP, TENSP) do "Thai Lan" sản xuất có giá bằng 1 trong 3 mức giá cao nhất (của tất cả các sản phẩm).
- In ra danh sách các sản phẩm (MASP, TENSP) do "Trung Quoc" sản xuất có giá bằng 1 trong 3 mức giá cao nhất (của sản phẩm do "Trung Quoc" sản xuất).
- In ra danh sách khách hàng nằm trong 3 hạng cao nhất (xếp hạng theo doanh số).
- Tính tổng số sản phẩm do "Trung Quoc" sản xuất.
- Tính tổng số sản phẩm của từng nước sản xuất.
- Với từng nước sản xuất, tìm giá bán cao nhất, thấp nhất, trung bình của các sản phẩm.
- Tính doanh thu bán hàng mỗi ngày.
- Tính tổng số lượng của từng sản phẩm bán ra trong tháng 10/2006.
- Tính doanh thu bán hàng của từng tháng trong năm 2006.
- Tìm hóa đơn có mua ít nhất 4 sản phẩm khác nhau.
- Tìm hóa đơn có mua 3 sản phẩm do "Viet Nam" sản xuất (3 sản phẩm khác nhau).
- Tìm khách hàng (MAKH, HOTEN) có số lần mua hàng nhiều nhất.
- Tháng mấy trong năm 2006, doanh số bán hàng cao nhất?
- Tìm sản phẩm (MASP, TENSP) có tổng số lượng bán ra thấp nhất trong năm 2006.
- Mỗi nước sản xuất, tìm sản phẩm (MASP, TENSP) có giá bán cao nhất.
- Tìm nước sản xuất sản xuất ít nhất 3 sản phẩm có giá bán khác nhau.
- Trong 10 khách hàng có doanh số cao nhất, tìm khách hàng có số lần mua hàng nhiều nhất.
ĐÁP ÁN
Xem đáp án
Nội dung được bảo vệ
Nhập mã truy cập để xem đáp án Tuần 3.
Mã truy cập được cung cấp bởi giảng viên.
Đáp án cho Câu 26 đến Câu 53. Gõ lại từng câu vào SSMS để nhớ lâu hơn nhé - Nút Copy ở đây chỉ mang tính hình thức thôi.
CÂU 26 · PHÉP CHIA QUAN HỆ
Đề bài: Tìm số hóa đơn đã mua tất cả các sản phẩm do Singapore sản xuất.
SELECT hd.SOHD
FROM HOADON hd
WHERE NOT EXISTS (
SELECT * FROM SANPHAM sp
WHERE sp.NUOCSX = 'Singapore'
AND NOT EXISTS (
SELECT * FROM CTHD ct
WHERE ct.MASP = sp.MASP AND ct.SOHD = hd.SOHD
)
);Phép chia: Tìm hóa đơn mà không tồn tại sản phẩm Singapore nào chưa xuất hiện trong CTHD của hóa đơn đó.
SQL Server không có toán tử chia trực tiếp, nên phải lập luận ngược bằng NOT EXISTS lồng nhau - Đây là cách chuẩn để giải các đề "mua tất cả/dạy tất cả".
Cách khác
SELECT hd.SOHD
FROM HOADON hd
JOIN CTHD ct ON hd.SOHD = ct.SOHD
JOIN SANPHAM sp ON sp.MASP = ct.MASP
WHERE sp.NUOCSX = 'Singapore'
GROUP BY hd.SOHD
HAVING COUNT(DISTINCT sp.MASP) = (
SELECT COUNT(*) FROM SANPHAM WHERE NUOCSX = 'Singapore'
);CÂU 27 · PHÉP CHIA + WHERE
Đề bài: Tìm số hóa đơn trong năm 2006 đã mua tất cả các sản phẩm do Singapore sản xuất.
SELECT hd.SOHD
FROM HOADON hd
WHERE YEAR(hd.NGHD) = 2006
AND NOT EXISTS (
SELECT * FROM SANPHAM sp
WHERE sp.NUOCSX = 'Singapore'
AND NOT EXISTS (
SELECT * FROM CTHD ct
WHERE ct.MASP = sp.MASP AND ct.SOHD = hd.SOHD
)
);Y hệt Câu 26, chỉ thêm điều kiện YEAR(NGHD) = 2006 trên hóa đơn ngoài cùng.
Điều kiện năm chỉ áp dụng cho hóa đơn đang xét (bảng ngoài), không liên quan gì đến phép chia bên trong - Nên thêm thẳng vào WHERE của truy vấn chính.
CÂU 28 · IS NULL
Đề bài: Có bao nhiêu hóa đơn không phải của khách hàng đăng ký thành viên mua?
SELECT COUNT(*) AS SLHoaDon
FROM HOADON
WHERE MAKH IS NULL;MAKH IS NULL đúng nghĩa với hóa đơn không gắn khách hàng thành viên nào.
Không được viết MAKH = NULL - Trong SQL, so sánh bằng với NULL luôn cho kết quả không xác định, phải dùng IS NULL.
CÂU 29 · COUNT DISTINCT
Đề bài: Có bao nhiêu sản phẩm khác nhau được bán ra trong năm 2006.
SELECT COUNT(DISTINCT ct.MASP) AS SLSanPham
FROM CTHD ct
JOIN HOADON hd ON ct.SOHD = hd.SOHD
WHERE YEAR(hd.NGHD) = 2006;COUNT(DISTINCT ...) đếm số giá trị khác nhau, loại bỏ trùng lặp.
1 sản phẩm có thể xuất hiện ở nhiều dòng CTHD (nhiều hóa đơn khác nhau) - Nếu chỉ COUNT(*) sẽ đếm trùng, phải dùng DISTINCT trên MASP.
CÂU 30 · MAX/MIN
Đề bài: Cho biết trị giá hóa đơn cao nhất, thấp nhất là bao nhiêu?
SELECT MAX(TRIGIA) AS TriGiaCaoNhat, MIN(TRIGIA) AS TriGiaThapNhat
FROM HOADON;MAX/MIN tính trực tiếp trên toàn bộ cột TRIGIA, không cần GROUP BY vì chỉ cần 1 dòng kết quả duy nhất.
Đề chỉ hỏi giá trị cao nhất/thấp nhất (2 con số), chưa hỏi hóa đơn nào - Nên không cần JOIN hay lọc thêm gì khác.
CÂU 31 · AVG + WHERE
Đề bài: Trị giá trung bình của tất cả các hóa đơn được bán ra trong năm 2006 là bao nhiêu?
SELECT AVG(TRIGIA) AS TriGiaTrungBinh
FROM HOADON
WHERE YEAR(NGHD) = 2006;AVG tính giá trị trung bình của các dòng còn lại sau khi WHERE đã lọc theo năm.
WHERE chạy trước hàm tổng hợp nên lọc năm ở đây là đúng chỗ - Không cần GROUP BY/HAVING vì không tách theo nhóm nào cả.
CÂU 32 · SUM
Đề bài: Tính doanh thu bán hàng trong năm 2006.
SELECT SUM(TRIGIA) AS DoanhThu
FROM HOADON
WHERE YEAR(NGHD) = 2006;SUM(TRIGIA) cộng dồn trị giá tất cả hóa đơn còn lại sau khi lọc năm.
"Doanh thu" = tổng trị giá các hóa đơn, khác với "trung bình" ở Câu 31 - Chỉ đổi AVG thành SUM, cấu trúc còn lại giữ nguyên.
CÂU 33 · SUBQUERY MAX theo năm
Đề bài: Tìm số hóa đơn có trị giá cao nhất trong năm 2006.
SELECT SOHD
FROM HOADON
WHERE YEAR(NGHD) = 2006
AND TRIGIA = (
SELECT MAX(TRIGIA) FROM HOADON WHERE YEAR(NGHD) = 2006
);Subquery tính giá trị MAX(TRIGIA) chỉ trong năm 2006, rồi truy vấn ngoài lọc đúng hóa đơn có trị giá bằng con số đó.
Cả subquery lẫn truy vấn ngoài đều phải lọc năm 2006 - Nếu chỉ lọc 1 trong 2 chỗ, kết quả có thể lẫn hóa đơn của năm khác trùng trị giá với hóa đơn cao nhất năm 2006.
Cách khác
SELECT TOP 1 WITH TIES SOHD
FROM HOADON
WHERE YEAR(NGHD) = 2006
ORDER BY TRIGIA DESC;CÂU 34 · JOIN + TOP WITH TIES
Đề bài: Tìm họ tên khách hàng đã mua hóa đơn có trị giá cao nhất trong năm 2006.
SELECT TOP 1 WITH TIES hd.MAKH, kh.HOTEN, hd.SOHD, hd.TRIGIA
FROM KHACHHANG kh
JOIN HOADON hd ON kh.MAKH = hd.MAKH
WHERE YEAR(hd.NGHD) = 2006
ORDER BY hd.TRIGIA DESC;TOP 1 WITH TIES ... ORDER BY TRIGIA DESC lấy (các) hóa đơn cao nhất, kèm luôn thông tin khách hàng qua JOIN.
WITH TIES đảm bảo nếu có nhiều hóa đơn cùng đồng hạng cao nhất thì lấy đủ tất cả, không bỏ sót - Khác với TOP 1 thường chỉ lấy đúng 1 dòng.
CÂU 35 · TOP + ORDER BY
Đề bài: In ra danh sách 3 khách hàng đầu tiên (MAKH, HOTEN) sắp xếp theo doanh số giảm dần.
SELECT TOP 3 MAKH, HOTEN
FROM KHACHHANG
ORDER BY DOANHSO DESC;TOP 3 lấy đúng 3 dòng đầu sau khi đã sắp xếp giảm dần theo DOANHSO.
Đề yêu cầu đúng "3 khách hàng đầu tiên" (không phải "3 hạng cao nhất" như Câu 39) nên dùng TOP 3 thường, không cần WITH TIES.
CÂU 36 · DISTINCT TOP trong IN
Đề bài: In ra danh sách các sản phẩm (MASP, TENSP) có giá bán bằng 1 trong 3 mức giá cao nhất.
SELECT MASP, TENSP
FROM SANPHAM
WHERE GIA IN (
SELECT DISTINCT TOP 3 GIA FROM SANPHAM ORDER BY GIA DESC
);SELECT DISTINCT TOP 3 GIA ... ORDER BY GIA DESC lấy ra 3 mức giá (không phải 3 sản phẩm) cao nhất, khác nhau.
Nhiều sản phẩm có thể trùng giá - Nếu không DISTINCT, "3 mức giá cao nhất" có thể chỉ ra 1-2 mức giá thực sự do trùng lặp trong TOP 3.
CÂU 37 · Lọc thêm sau khi có 3 mức giá
Đề bài: In ra danh sách các sản phẩm (MASP, TENSP) do "Thai Lan" sản xuất có giá bằng 1 trong 3 mức giá cao nhất (của tất cả các sản phẩm).
SELECT MASP, TENSP
FROM SANPHAM
WHERE NUOCSX = 'Thai Lan'
AND GIA IN (
SELECT DISTINCT TOP 3 GIA FROM SANPHAM ORDER BY GIA DESC
);Giống Câu 36, thêm điều kiện NUOCSX = 'Thai Lan' ở truy vấn ngoài.
Subquery tính 3 mức giá cao nhất trên toàn bộ sản phẩm (không lọc nước sản xuất) - Vì đề nói rõ "của tất cả các sản phẩm", chỉ lọc Thái Lan ở ngoài.
CÂU 38 · Subquery cũng lọc theo nước SX
Đề bài: In ra danh sách các sản phẩm (MASP, TENSP) do "Trung Quoc" sản xuất có giá bằng 1 trong 3 mức giá cao nhất (của sản phẩm do "Trung Quoc" sản xuất).
SELECT MASP, TENSP
FROM SANPHAM
WHERE NUOCSX = 'Trung Quoc'
AND GIA IN (
SELECT DISTINCT TOP 3 GIA FROM SANPHAM
WHERE NUOCSX = 'Trung Quoc'
ORDER BY GIA DESC
);Khác Câu 37 ở chỗ subquery cũng lọc NUOCSX = 'Trung Quoc' - 3 mức giá cao nhất được tính riêng trong nhóm Trung Quốc.
Đề nói rõ "của sản phẩm do Trung Quốc sản xuất" (khác cách nói "của tất cả các sản phẩm" ở Câu 37) - Đọc kỹ phần chú thích trong ngoặc để biết lọc ở subquery hay không.
CÂU 39 · TOP WITH TIES theo doanh số
Đề bài: In ra danh sách khách hàng nằm trong 3 hạng cao nhất (xếp hạng theo doanh số).
SELECT TOP 3 WITH TIES MAKH, HOTEN, DOANHSO
FROM KHACHHANG
ORDER BY DOANHSO DESC;TOP 3 WITH TIES lấy đủ mọi khách hàng thuộc 3 mức doanh số cao nhất, kể cả khi nhiều người cùng 1 mức.
Khác Câu 35 ("3 khách hàng đầu tiên" - Đúng 3 dòng), đây là "3 hạng" - Nếu 2 khách hàng đồng hạng 3 thì cả 2 đều phải xuất hiện, nên bắt buộc dùng WITH TIES.
Cách khác
SELECT MAKH, HOTEN, DOANHSO
FROM KHACHHANG
WHERE DOANHSO IN (
SELECT DISTINCT TOP 3 DOANHSO FROM KHACHHANG ORDER BY DOANHSO DESC
);CÂU 40 · COUNT + WHERE
Đề bài: Tính tổng số sản phẩm do "Trung Quoc" sản xuất.
SELECT COUNT(*) AS SLSanPham
FROM SANPHAM
WHERE NUOCSX = 'Trung Quoc';COUNT(*) đếm số dòng còn lại sau khi WHERE lọc đúng nước sản xuất.
Câu hỏi đơn giản chỉ cần đếm trên 1 điều kiện duy nhất, không cần GROUP BY vì không tách theo nhóm nào.
CÂU 41 · GROUP BY + COUNT
Đề bài: Tính tổng số sản phẩm của từng nước sản xuất.
SELECT NUOCSX, COUNT(*) AS SLSanPham
FROM SANPHAM
GROUP BY NUOCSX;GROUP BY NUOCSX gom sản phẩm theo từng nước, COUNT(*) đếm số sản phẩm trong mỗi nhóm.
"Của từng nước sản xuất" là dấu hiệu rõ ràng của GROUP BY - Khác Câu 40 chỉ hỏi 1 nước cụ thể (Trung Quốc).
CÂU 42 · GROUP BY nhiều hàm tổng hợp
Đề bài: Với từng nước sản xuất, tìm giá bán cao nhất, thấp nhất, trung bình của các sản phẩm.
SELECT NUOCSX, MAX(GIA) AS GiaCaoNhat, MIN(GIA) AS GiaThapNhat, AVG(GIA) AS GiaTrungBinh
FROM SANPHAM
GROUP BY NUOCSX;Có thể tính nhiều hàm tổng hợp (MAX, MIN, AVG) cùng lúc trong 1 SELECT, miễn là cùng theo 1 GROUP BY.
Không cần viết 3 câu truy vấn riêng - Mỗi hàm tổng hợp tự tính trên từng nhóm NUOCSX độc lập với nhau trong cùng 1 lượt quét dữ liệu.
CÂU 43 · GROUP BY theo ngày
Đề bài: Tính doanh thu bán hàng mỗi ngày.
SELECT NGHD, SUM(TRIGIA) AS DoanhThu
FROM HOADON
GROUP BY NGHD;GROUP BY NGHD gom các hóa đơn cùng ngày lập thành 1 nhóm, SUM(TRIGIA) cộng dồn trị giá trong ngày đó.
"Mỗi ngày" nghĩa là tách kết quả theo từng giá trị NGHD khác nhau - Đúng bản chất của GROUP BY.
CÂU 44 · GROUP BY + WHERE nhiều điều kiện
Đề bài: Tính tổng số lượng của từng sản phẩm bán ra trong tháng 10/2006.
SELECT ct.MASP, SUM(ct.SL) AS SLSP
FROM CTHD ct
JOIN HOADON hd ON ct.SOHD = hd.SOHD
WHERE YEAR(hd.NGHD) = 2006 AND MONTH(hd.NGHD) = 10
GROUP BY ct.MASP;WHERE lọc đúng tháng 10/2006 trước, sau đó GROUP BY MASP mới cộng dồn số lượng theo từng sản phẩm.
Số lượng nằm ở CTHD nhưng ngày lại nằm ở HOADON - Phải JOIN 2 bảng lại mới lọc được đúng khoảng thời gian.
CÂU 45 · GROUP BY theo tháng
Đề bài: Tính doanh thu bán hàng của từng tháng trong năm 2006.
SELECT MONTH(NGHD) AS Thang, SUM(TRIGIA) AS DoanhThu
FROM HOADON
WHERE YEAR(NGHD) = 2006
GROUP BY MONTH(NGHD);Có thể GROUP BY trực tiếp trên kết quả của 1 hàm (MONTH(NGHD)), không bắt buộc phải là tên cột gốc.
Cần gom theo tháng (1-12) chứ không phải theo từng ngày cụ thể như Câu 43 - MONTH() "làm tròn" ngày về tháng trước khi gom nhóm.
CÂU 46 · HAVING COUNT DISTINCT
Đề bài: Tìm hóa đơn có mua ít nhất 4 sản phẩm khác nhau.
SELECT hd.SOHD, COUNT(DISTINCT ct.MASP) AS SLSP
FROM HOADON hd
JOIN CTHD ct ON hd.SOHD = ct.SOHD
GROUP BY hd.SOHD
HAVING COUNT(DISTINCT ct.MASP) >= 4;HAVING COUNT(DISTINCT MASP) >= 4 chỉ giữ lại hóa đơn có từ 4 mã sản phẩm khác nhau trở lên.
"4 sản phẩm khác nhau" bắt buộc phải DISTINCT - Nếu chỉ COUNT(*), 1 sản phẩm mua số lượng nhiều vẫn có thể bị đếm là "nhiều sản phẩm" (sai).
CÂU 47 · JOIN 3 bảng + HAVING
Đề bài: Tìm hóa đơn có mua 3 sản phẩm do "Viet Nam" sản xuất (3 sản phẩm khác nhau).
SELECT hd.SOHD, COUNT(DISTINCT ct.MASP) AS SLSP
FROM HOADON hd
JOIN CTHD ct ON hd.SOHD = ct.SOHD
JOIN SANPHAM sp ON sp.MASP = ct.MASP
WHERE sp.NUOCSX = 'Viet Nam'
GROUP BY hd.SOHD
HAVING COUNT(DISTINCT ct.MASP) >= 3;Giống Câu 46, thêm JOIN SANPHAM để lọc riêng sản phẩm do "Viet Nam" sản xuất trước khi đếm.
WHERE lọc nước sản xuất phải chạy trước GROUP BY, để COUNT(DISTINCT ...) chỉ đếm đúng sản phẩm Việt Nam, không tính sản phẩm nước khác trong cùng hóa đơn.
CÂU 48 · TOP WITH TIES + COUNT
Đề bài: Tìm khách hàng (MAKH, HOTEN) có số lần mua hàng nhiều nhất.
SELECT TOP 1 WITH TIES hd.MAKH, kh.HOTEN, COUNT(DISTINCT hd.SOHD) AS SLMH
FROM HOADON hd
JOIN KHACHHANG kh ON hd.MAKH = kh.MAKH
GROUP BY hd.MAKH, kh.HOTEN
ORDER BY SLMH DESC;"Số lần mua hàng" = số hóa đơn khác nhau của khách hàng đó, nên GROUP BY theo khách hàng rồi đếm SOHD.
TOP 1 WITH TIES đảm bảo nếu có nhiều khách hàng cùng mua nhiều lần nhất thì liệt kê đủ, không chỉ chọn ngẫu nhiên 1 người.
CÂU 49 · GROUP BY + TOP WITH TIES
Đề bài: Tháng mấy trong năm 2006, doanh số bán hàng cao nhất?
SELECT TOP 1 WITH TIES MONTH(NGHD) AS Thang, SUM(TRIGIA) AS DoanhThu
FROM HOADON
WHERE YEAR(NGHD) = 2006
GROUP BY MONTH(NGHD)
ORDER BY DoanhThu DESC;Tính doanh thu từng tháng như Câu 45, sau đó ORDER BY DoanhThu DESC + TOP 1 WITH TIES để lấy tháng cao nhất.
Phải tính xong doanh thu theo tháng (GROUP BY) rồi mới so sánh được tháng nào cao nhất - Không thể lấy MAX trực tiếp vì còn cần biết đó là tháng mấy.
CÂU 50 · ORDER BY ASC
Đề bài: Tìm sản phẩm (MASP, TENSP) có tổng số lượng bán ra thấp nhất trong năm 2006.
SELECT TOP 1 WITH TIES ct.MASP, sp.TENSP, SUM(ct.SL) AS SLSP
FROM CTHD ct
JOIN HOADON hd ON ct.SOHD = hd.SOHD
JOIN SANPHAM sp ON sp.MASP = ct.MASP
WHERE YEAR(hd.NGHD) = 2006
GROUP BY ct.MASP, sp.TENSP
ORDER BY SLSP ASC;Giống cấu trúc Câu 44 (tổng số lượng theo sản phẩm), chỉ đổi ORDER BY ... ASC (tăng dần) để lấy sản phẩm bán ít nhất.
ASC là chiều mặc định của ORDER BY nhưng vẫn nên ghi rõ ra để code dễ đọc, đặc biệt khi đề bài đổi giữa "cao nhất"/"thấp nhất" liên tục.
CÂU 51 · Correlated subquery
Đề bài: Mỗi nước sản xuất, tìm sản phẩm (MASP, TENSP) có giá bán cao nhất.
SELECT sp.NUOCSX, sp.MASP, sp.TENSP
FROM SANPHAM sp
WHERE sp.GIA = (
SELECT MAX(sp1.GIA)
FROM SANPHAM sp1
WHERE sp1.NUOCSX = sp.NUOCSX
);Correlated subquery: Với mỗi dòng sp ở ngoài, subquery bên trong tự tính lại MAX(GIA) riêng cho đúng NUOCSX của dòng đó.
Khác Câu 42 (chỉ cần con số tổng hợp), đề này cần biết luôn MASP/TENSP của sản phẩm giá cao nhất - GROUP BY thường không lấy kèm được tên sản phẩm, nên phải dùng correlated subquery.
CÂU 52 · HAVING COUNT DISTINCT
Đề bài: Tìm nước sản xuất sản xuất ít nhất 3 sản phẩm có giá bán khác nhau.
SELECT NUOCSX, COUNT(DISTINCT GIA) AS GiaBanKhacNhau
FROM SANPHAM
GROUP BY NUOCSX
HAVING COUNT(DISTINCT GIA) >= 3;HAVING COUNT(DISTINCT GIA) >= 3 chỉ giữ lại nước có từ 3 mức giá khác nhau trở lên.
Lưu ý DISTINCT phải nằm trong cả HAVING, không chỉ ở tên cột hiển thị - Nếu HAVING chỉ viết COUNT(GIA) >= 3 (thiếu DISTINCT) thì lại đang đếm "ít nhất 3 sản phẩm" chứ không phải "3 mức giá khác nhau", sai với đề.
CÂU 53 · Subquery TOP WITH TIES + GROUP BY
Đề bài: Trong 10 khách hàng có doanh số cao nhất, tìm khách hàng có số lần mua hàng nhiều nhất.
SELECT TOP 1 WITH TIES hd.MAKH, kh.HOTEN, COUNT(hd.SOHD) AS SLMH
FROM KHACHHANG kh
JOIN HOADON hd ON kh.MAKH = hd.MAKH
WHERE hd.MAKH IN (
SELECT TOP 10 WITH TIES MAKH FROM KHACHHANG ORDER BY DOANHSO DESC
)
GROUP BY hd.MAKH, kh.HOTEN
ORDER BY SLMH DESC;Subquery lọc ra 10 khách hàng doanh số cao nhất trước, truy vấn ngoài chỉ đếm số lần mua hàng trong phạm vi 10 người đó.
Đây là bài toán 2 tầng: "lọc top 10" và "tìm người mua nhiều lần nhất" là 2 tiêu chí khác nhau (doanh số vs. số lần mua) - Không thể gộp chung 1 ORDER BY duy nhất, phải tách thành subquery riêng.
