Để tránh các kết quả bất ngờ tiềm ẩn khi sử dụng GROUP BY
mà không có hàm tổng hợp, như được sử dụng trong câu trả lời được chấp nhận , bởi vì MySQL có thể tự do lấy bất kỳ giá trị nào trong tập dữ liệu được nhóm khi không sử dụng hàm tổng hợp [sic] và các vấn đề với ONLY_FULL_GROUP_BY
. Vui lòng xem xét sử dụng một tham gia loại trừ.
Loại trừ Tham gia - Các thực thể không rõ ràng
Giả sử tên và họ được lập chỉ mục duy nhất (không rõ ràng) , một cách khác GROUP BY
là sắp xếp bằng cách sử dụng một LEFT JOIN
bộ lọc kết quả, còn được gọi là THAM GIA loại trừ.
Xem Trình diễn
Thứ tự tăng dần (AZ)
Để lấy tên riêng biệt được đặt theo tên cuối cùng từ AZ
Truy vấn
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname > t2.lastname
WHERE t2.id IS NULL;
Kết quả
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
Thứ tự giảm dần (ZA)
Để lấy tên riêng biệt được đặt theo tên cuối cùng từ ZA
Truy vấn
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname < t2.lastname
WHERE t2.id IS NULL;
Kết quả
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
Sau đó, bạn có thể đặt dữ liệu kết quả như mong muốn.
Tham gia loại trừ - Các thực thể mơ hồ
Nếu kết hợp tên và họ không phải là duy nhất (không rõ ràng) và bạn có nhiều hàng có cùng giá trị, bạn có thể lọc kết quả được đặt bằng cách bao gồm một điều kiện OR trên tiêu chí THAM GIA để lọc theo id.
Xem Trình diễn
dữ liệu tên_bảng
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson'),
(4, 'John', 'Doe'),
(5, 'John', 'Johnson')
Truy vấn
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND (t1.lastname > t2.lastname
OR (t1.firstname = t1.firstname AND t1.lastname = t2.lastname AND t1.id > t2.id))
WHERE t2.id IS NULL;
Kết quả
| id | firstname | lastname |
|----|-----------|----------|
| 1 | John | Doe |
| 2 | Bugs | Bunny |
Đặt hàng Subquery
BIÊN TẬP
Câu trả lời ban đầu của tôi bằng cách sử dụng truy vấn con được đặt hàng , được viết trước MySQL 5.7.5 , không còn áp dụng được, do những thay đổi với ONLY_FULL_GROUP_BY
. Vui lòng sử dụng các ví dụ tham gia loại trừ ở trên thay thế.
Nó cũng quan trọng cần lưu ý; khi ONLY_FULL_GROUP_BY
bị vô hiệu hóa (hành vi ban đầu trước MySQL 5.7.5) , việc sử dụng GROUP BY
không có hàm tổng hợp có thể mang lại kết quả không mong muốn, vì MySQL có thể tự do chọn BẤT K value giá trị nào trong tập dữ liệu được nhóm [sic] .
Có nghĩa là một ID
hoặc lastname
giá trị có thể được lấy mà không được liên kết với firstname
hàng được lấy .
CẢNH BÁO
Với MySQL GROUP BY
có thể không mang lại kết quả như mong đợi khi được sử dụng vớiORDER BY
Xem ví dụ trường hợp thử nghiệm
Phương pháp thực hiện tốt nhất, để đảm bảo kết quả mong đợi, là lọc phạm vi tập kết quả bằng cách sử dụng truy vấn con được đặt hàng.
dữ liệu tên_bảng
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson')
Truy vấn
SELECT * FROM (
SELECT * FROM table_name ORDER BY ID DESC
) AS t1
GROUP BY FirstName
Kết quả
| ID | first | last |
|----|-------|---------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
So sánh
Để chứng minh kết quả bất ngờ khi sử dụng GROUP BY
kết hợp vớiORDER BY
Truy vấn
SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC
Kết quả
| ID | first | last |
|----|-------|-------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |