PILIH ... LIMIT tidak didukung di subkueri, saya khawatir, jadi inilah saatnya untuk memecahkan keajaiban bergabung-sendiri:
SELECT article.*
FROM article
JOIN (
SELECT a0.category_id AS id, MIN(a2.article_id) AS lim
FROM article AS a0
LEFT JOIN article AS a1 ON a1.category_id=a0.category_id AND a1.article_id>a0.article_id
LEFT JOIN article AS a2 ON a2.category_id=a1.category_id AND a2.article_id>a1.article_id
GROUP BY id
) AS cat ON cat.id=article.category_id
WHERE article.article_id<=cat.lim OR cat.lim IS NULL
ORDER BY article_id;
Bagian di tengah mengerjakan ID artikel dengan ID terendah ketiga untuk setiap kategori dengan mencoba menggabungkan tiga salinan dari tabel yang sama dalam urutan ID menaik. Jika ada kurang dari tiga artikel untuk suatu kategori, gabungan kiri akan memastikan batasnya NULL, sehingga WHERE luar perlu mengambil kasus itu juga.
Jika persyaratan "3 teratas" Anda mungkin berubah menjadi "n teratas" di beberapa titik, ini mulai menjadi berat. Dalam hal ini, Anda mungkin ingin mempertimbangkan kembali gagasan untuk membuat kueri daftar kategori yang berbeda terlebih dahulu, lalu menggabungkan kueri per kategori.
ETA:Memesan pada dua kolom:eek, persyaratan baru! :-)
Itu tergantung apa yang Anda maksud:jika Anda hanya mencoba memesan hasil akhir, Anda dapat memukulnya di akhir tanpa masalah. Tetapi jika Anda perlu menggunakan urutan ini untuk memilih tiga artikel mana yang akan dipilih, semuanya akan jauh lebih sulit.
Kami menggunakan self-join dengan '<' untuk mereproduksi efek yang akan dimiliki 'ORDER BY article_id'. Sayangnya, sementara Anda bisa melakukan 'ORDER BY a, b', Anda tidak bisa lakukan '(a, b)<(c, d)'... kamu juga tidak bisa melakukan 'MIN(a, b)'. Plus, Anda sebenarnya akan memesan dengan tiga kolom, issticky, diterbitkan dan article_id, karena Anda perlu memastikan bahwa setiap nilai pemesanan unik, untuk menghindari pengembalian empat baris atau lebih.
Sementara Anda bisa buat nilai pesanan Anda sendiri dengan beberapa bilangan bulat mentah atau kombinasi string kolom:
LEFT JOIN article AS a1
ON a1.category_id=a0.category_id
AND HEX(a1.issticky)+HEX(a1.published_at)+HEX(a1.article_id)>HEX(a0.issticky)+HEX(a0.published_at)+HEX(a0.article_id)
ini menjadi sangat buruk, dan perhitungannya akan menyia-nyiakan kesempatan menggunakan indeks untuk membuat kueri menjadi efisien. Pada titik mana Anda lebih baik hanya melakukan kueri TERBATAS per kategori yang terpisah.