Giải pháp của bạn sử dụng phần mở rộng cho mệnh đề GROUP BY cho phép nhóm theo một số trường (trong trường hợp này, chỉ post_author
):
GROUP BY wp_posts.post_author
và chọn các cột không kết hợp:
SELECT wp_posts.*
không được liệt kê trong nhóm theo mệnh đề hoặc không được sử dụng trong hàm tổng hợp (MIN, MAX, COUNT, v.v.).
Sử dụng đúng phần mở rộng cho mệnh đề GROUP BY
Điều này hữu ích khi tất cả các giá trị của các cột không tổng hợp đều bằng nhau cho mỗi hàng.
Ví dụ: giả sử bạn có một cái bàn GardensFlowers
( name
của khu vườn, flower
mọc trong vườn):
INSERT INTO GardensFlowers VALUES
('Central Park', 'Magnolia'),
('Hyde Park', 'Tulip'),
('Gardens By The Bay', 'Peony'),
('Gardens By The Bay', 'Cherry Blossom');
và bạn muốn trích xuất tất cả những bông hoa mọc trong một khu vườn, nơi có nhiều hoa mọc lên. Sau đó, bạn phải sử dụng một truy vấn con, ví dụ bạn có thể sử dụng điều này:
SELECT GardensFlowers.*
FROM GardensFlowers
WHERE name IN (SELECT name
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)>1);
Thay vào đó, nếu bạn cần trích xuất tất cả những bông hoa là hoa duy nhất trong vườn, bạn có thể thay đổi điều kiện HAVING thành HAVING COUNT(DISTINCT flower)=1
, nhưng MySql cũng cho phép bạn sử dụng điều này:
SELECT GardensFlowers.*
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)=1;
không truy vấn con, không phải SQL chuẩn, nhưng đơn giản hơn.
Sử dụng không chính xác phần mở rộng cho mệnh đề GROUP BY
Nhưng điều gì xảy ra nếu bạn CHỌN các cột không tổng hợp không bằng nhau cho mỗi hàng? Giá trị mà MySql chọn cho cột đó là gì?
Có vẻ như MySql luôn chọn FIRST giá trị mà nó gặp phải.
Để đảm bảo rằng giá trị đầu tiên mà nó gặp phải chính xác là giá trị bạn muốn, bạn cần áp dụng một GROUP BY
truy vấn theo thứ tự, do đó cần phải sử dụng truy vấn con. Bạn không thể làm điều đó khác.
Giả định rằng MySql luôn chọn hàng đầu tiên mà nó gặp, bạn đang sắp xếp chính xác các hàng trước NHÓM THEO. Nhưng thật không may, nếu bạn đọc tài liệu cẩn thận, bạn sẽ nhận thấy rằng giả định này không đúng.
Khi chọn các cột không tổng hợp không phải lúc nào cũng giống nhau, MySql có thể tự do chọn bất kỳ giá trị nào, vì vậy giá trị kết quả mà nó thực sự hiển thị là không xác định .
Tôi thấy rằng thủ thuật này để có được giá trị đầu tiên của một cột không tổng hợp được sử dụng rất nhiều và nó thường / hầu như luôn hoạt động, đôi khi tôi cũng sử dụng nó (có nguy cơ của riêng tôi). Nhưng vì nó không được ghi lại, bạn không thể dựa vào hành vi này.
Liên kết này (cảm ơn ypercube!) Thủ thuật GROUP BY đã được tối ưu hóa cho thấy một tình huống trong đó cùng một truy vấn trả về các kết quả khác nhau giữa MySql và MariaDB, có thể là do một công cụ tối ưu hóa khác nhau.
Vì vậy, nếu thủ thuật này hoạt động, đó chỉ là vấn đề may mắn.
Các câu trả lời được chấp nhận về vấn đề khác trông không đúng với tôi:
HAVING wp_posts.post_date = MAX(wp_posts.post_date)
wp_posts.post_date
là một cột không tổng hợp và giá trị của nó sẽ chính thức không được xác định, nhưng nó có thể sẽ là lần đầu tiên post_date
gặp phải. Nhưng vì thủ thuật GROUP BY được áp dụng cho một bảng không có thứ tự, nên không chắc cái nào là đầu tiênpost_date
gặp phải.
Nó có thể sẽ trả về các bài đăng là bài viết duy nhất của một tác giả, nhưng ngay cả điều này không phải lúc nào cũng chắc chắn.
Một giải pháp khả thi
Tôi nghĩ rằng đây có thể là một giải pháp khả thi:
SELECT wp_posts.*
FROM wp_posts
WHERE id IN (
SELECT max(id)
FROM wp_posts
WHERE (post_author, post_date) = (
SELECT post_author, max(post_date)
FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY post_author
) AND wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY post_author
)
Trên truy vấn bên trong, tôi sẽ trả lại ngày đăng tối đa cho mỗi tác giả. Sau đó, tôi đang xem xét thực tế rằng cùng một tác giả về mặt lý thuyết có thể có hai bài đăng cùng một lúc, vì vậy tôi chỉ nhận được ID tối đa. Và sau đó tôi sẽ trả lại tất cả các hàng có ID tối đa đó. Nó có thể được thực hiện nhanh hơn bằng cách sử dụng các phép nối thay vì mệnh đề IN.
(Nếu bạn chắc chắn rằng ID
nó chỉ tăng và nếu ID1 > ID2
cũng có nghĩa là post_date1 > post_date2
, thì truy vấn có thể được thực hiện đơn giản hơn nhiều, nhưng tôi không chắc liệu đây có phải là trường hợp không).
post_author
vàpost_date
không đủ để có được một hàng duy nhất, vì vậy cần phải có nhiều hơn để có một hàng duy nhất cho mỗipost_author