Berikut triknya:menghitung SUM()
nilai yang diketahui 1 atau 0 setara dengan COUNT()
dari baris dengan nilai 1. Dan Anda tahu bahwa perbandingan boolean menghasilkan 1 atau 0 (atau NULL).
SELECT c.catname, COUNT(m.catid) AS item_count,
SUM(i.ownerid = @ownerid) AS owner_item_count
FROM categories c
LEFT JOIN map m USING (catid)
LEFT JOIN items i USING (itemid)
GROUP BY c.catid;
Adapun pertanyaan bonus, Anda cukup melakukan gabungan dalam alih-alih gabungan luar, yang berarti hanya kategori dengan setidaknya satu baris di map
akan dikembalikan.
SELECT c.catname, COUNT(m.catid) AS item_count,
SUM(i.ownerid = @ownerid) AS owner_item_count
FROM categories c
INNER JOIN map m USING (catid)
INNER JOIN items i USING (itemid)
GROUP BY c.catid;
Inilah solusi lain, yang tidak seefisien tetapi saya akan menunjukkannya untuk menjelaskan mengapa Anda mendapatkan kesalahan:
SELECT c.catname, COUNT(m.catid) AS item_count,
SUM(i.ownerid = @ownerid) AS owner_item_count
FROM categories c
LEFT JOIN map m USING (catid)
LEFT JOIN items i USING (itemid)
GROUP BY c.catid
HAVING item_count > 0;
Anda tidak dapat menggunakan alias kolom di WHERE
klausa, karena ekspresi dalam WHERE
klausa dievaluasi sebelum ekspresi dalam daftar pilih. Dengan kata lain, nilai yang terkait dengan ekspresi daftar pilihan belum tersedia.
Anda dapat menggunakan alias kolom di GROUP BY
, HAVING
, dan ORDER BY
klausa. Klausa ini dijalankan setelah semua ekspresi dalam daftar pilihan telah dievaluasi.