Solusi Anda menggunakan ekstensi untuk klausa GROUP BY yang memungkinkan untuk dikelompokkan berdasarkan beberapa bidang (dalam hal ini, adil post_author
):
GROUP BY wp_posts.post_author
dan pilih kolom yang tidak teragregasi:
SELECT wp_posts.*
yang tidak tercantum dalam grup dengan klausa, atau yang tidak digunakan dalam fungsi agregat (MIN, MAX, COUNT, dll.).
Penggunaan ekstensi yang benar untuk klausa GROUP BY
Ini berguna ketika semua nilai kolom non-agregat sama untuk setiap baris.
Sebagai contoh, misalkan Anda memiliki meja GardensFlowers
( name
taman, flower
yang tumbuh di taman):
INSERT INTO GardensFlowers VALUES
('Central Park', 'Magnolia'),
('Hyde Park', 'Tulip'),
('Gardens By The Bay', 'Peony'),
('Gardens By The Bay', 'Cherry Blossom');
dan Anda ingin mengekstrak semua bunga yang tumbuh di taman, di mana banyak bunga tumbuh. Maka Anda harus menggunakan subquery, misalnya Anda bisa menggunakan ini:
SELECT GardensFlowers.*
FROM GardensFlowers
WHERE name IN (SELECT name
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)>1);
Jika Anda perlu mengekstrak semua bunga yang merupakan satu-satunya bunga di garder, Anda dapat mengubah kondisi HAVING HAVING COUNT(DISTINCT flower)=1
, tetapi MySql juga memungkinkan Anda untuk menggunakan ini:
SELECT GardensFlowers.*
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)=1;
tidak ada subquery, bukan SQL standar, tetapi lebih sederhana.
Penggunaan ekstensi yang salah untuk klausa GROUP BY
Tetapi apa yang terjadi jika Anda PILIH kolom non-agregat yang tidak sama untuk setiap baris? Nilai apa yang dipilih MySql untuk kolom itu?
Sepertinya MySql selalu memilih nilai PERTAMA yang dijumpainya.
Untuk memastikan bahwa nilai pertama yang dihadapinya persis dengan nilai yang Anda inginkan, Anda perlu menerapkan GROUP BY
kueri yang dipesan, maka kebutuhan untuk menggunakan subquery. Anda tidak bisa melakukannya sebaliknya.
Dengan asumsi bahwa MySql selalu memilih baris pertama yang dihadapinya, Anda dengan benar menyortir baris sebelum GROUP BY. Namun sayangnya, jika Anda membaca dokumentasi dengan cermat, Anda akan melihat bahwa asumsi ini tidak benar.
Saat memilih kolom non-agregat yang tidak selalu sama, MySql bebas memilih nilai apa pun, sehingga nilai yang dihasilkannya benar-benar tidak dapat ditentukan .
Saya melihat bahwa trik ini untuk mendapatkan nilai pertama dari kolom non-agregat banyak digunakan, dan biasanya / hampir selalu berhasil, saya kadang-kadang menggunakannya juga (dengan risiko saya sendiri). Tetapi karena itu tidak didokumentasikan, Anda tidak dapat mengandalkan perilaku ini.
Tautan ini (terima kasih ypercube!) Trik GROUP BY telah dioptimalkan menunjukkan situasi di mana permintaan yang sama mengembalikan hasil yang berbeda antara MySql dan MariaDB, mungkin karena mesin pengoptimalan yang berbeda.
Jadi, jika trik ini berhasil, itu hanya masalah keberuntungan.
The jawaban yang diterima pada pertanyaan lain terlihat salah kepada saya:
HAVING wp_posts.post_date = MAX(wp_posts.post_date)
wp_posts.post_date
adalah kolom non-agregat, dan nilainya akan secara resmi tidak ditentukan, tetapi kemungkinan akan menjadi yang pertama post_date
ditemui. Tetapi karena trik GROUP BY diterapkan pada tabel yang tidak berurutan, tidak yakin yang mana yang pertama kali post_date
ditemukan.
Mungkin akan mengembalikan posting yang merupakan satu-satunya posting dari penulis tunggal, tetapi bahkan ini tidak selalu pasti.
Solusi yang memungkinkan
Saya pikir ini bisa menjadi solusi yang mungkin:
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
)
Pada permintaan dalam, saya mengembalikan tanggal posting maksimum untuk setiap penulis. Saya kemudian mempertimbangkan fakta bahwa penulis yang sama secara teori dapat memiliki dua posting pada saat yang sama, jadi saya hanya mendapatkan ID maksimum. Dan kemudian saya mengembalikan semua baris yang memiliki ID maksimum itu. Itu bisa dibuat lebih cepat menggunakan gabungan bukannya klausa IN.
(Jika Anda yakin itu ID
hanya meningkat, dan jika ID1 > ID2
juga berarti demikian post_date1 > post_date2
, maka kueri dapat dibuat lebih sederhana, tapi saya tidak yakin apakah ini masalahnya).
post_author
danpost_date
tidak cukup untuk mendapatkan baris unik, jadi harus ada lebih banyak untuk mendapatkan baris unik perpost_author