Hitung dengan kondisi IF dalam query MySQL

115

Saya memiliki dua tabel, satu untuk berita dan satu lagi untuk komentar dan saya ingin menghitung jumlah komentar yang statusnya telah ditetapkan sebagai disetujui.

SELECT
    ccc_news . *, 
    count(if(ccc_news_comments.id = 'approved', ccc_news_comments.id, 0)) AS comments
FROM
    ccc_news
    LEFT JOIN
        ccc_news_comments
    ON ccc_news_comments.news_id = ccc_news.news_id
WHERE
    `ccc_news`.`category` = 'news_layer2'
    AND `ccc_news`.`status` = 'Active'
GROUP BY
    ccc_news.news_id
ORDER BY
    ccc_news.set_order ASC
LIMIT 20 

Tapi masalah dengan query ini adalah nilai minimum yang diambil untuk kolom komentar adalah 1 apakah ada komentar yang sesuai dengan berita itu atau tidak.

Bantuan apa pun akan sangat berarti.

pengguna1163513
sumber
5
Bagaimana jika Anda menggunakan SUM, bukan COUNT?
John Pick

Jawaban:

265

Gunakan sum()di tempatcount()

Coba di bawah ini:

SELECT
    ccc_news . * , 
    SUM(if(ccc_news_comments.id = 'approved', 1, 0)) AS comments
FROM
    ccc_news
    LEFT JOIN
        ccc_news_comments
    ON
        ccc_news_comments.news_id = ccc_news.news_id
WHERE
    `ccc_news`.`category` = 'news_layer2'
    AND `ccc_news`.`status` = 'Active'
GROUP BY
    ccc_news.news_id
ORDER BY
    ccc_news.set_order ASC
LIMIT 20 
ElChiniNet
sumber
11
Atau bahkan SUM (ccc_news_comments.id = 'disetujui') sebagai trik khusus MySQL
mojuba
1
@mojuba tidak 100% sama, trik Anda kembali nullketika COUNT(tidak ada kondisi) yang dikembalikan 0. Ketika COUNTakan pernah kembali apa-apa tapi 0, tetapi SUM tidak kembali 0, pengembalian trik Anda 0.
Robin Kanters
Kasus dan poin @mojuba . num_relevant_partsadalah SUMdengan kondisi, num_total_partsadalah COUNT(parts.id)(maaf untuk komentar ganda, terlambat untuk mengedit)
Robin Kanters
68

Lebih baik lagi (atau lebih pendek lagi):

SUM(ccc_news_comments.id = 'approved')

Ini berfungsi karena tipe Boolean di MySQL direpresentasikan sebagai INT 0dan 1, seperti di C. (Mungkin tidak portabel di seluruh sistem DB.)

Seperti yang COALESCE()disebutkan dalam jawaban lain, banyak API bahasa secara otomatis dikonversi NULLke ''saat mengambil nilainya. Misalnya dengan mysqliantarmuka PHP, akan aman untuk menjalankan kueri Anda tanpa COALESCE().

mojuba
sumber
3
Ini membuat kode sql jauh lebih mudah dibaca. Solusi yang bagus.
Dag Sondre Hansen
22

Ini harus bekerja:

count(if(ccc_news_comments.id = 'approved', ccc_news_comments.id, NULL))

count()hanya periksa apakah nilainya ada atau tidak. 0 setara dengan nilai yang ada, jadi ia menghitung satu lagi, sedangkan NULL seperti nilai yang tidak ada, jadi tidak dihitung.

Edemilson Lima
sumber
Saya pikir countlebih intuitif daripada sumdalam kasus ini.
Jeffery
4

Ganti baris ini:

count(if(ccc_news_comments.id = 'approved', ccc_news_comments.id, 0)) AS comments

Dengan yang ini:

coalesce(sum(ccc_news_comments.id = 'approved'), 0) comments
Mosty Mostacho
sumber
hitung (jika (ccc_news_comments.id = 'disetujui', ccc_news_comments.id, 0)) ??? apa artinya menggunakan sum jika Anda menggunakan ccc_news_comments.id
Maaf apa maksud anda Nilai boolean menjadi 0 atau 1, lalu jumlahkan, dan jika ada beberapa nilai nol bergabung dengan 0
Mosty Mostacho
@MostyMostacho, apakah COALESCEmengembalikan jumlahnya? Ada referensi di dokumen MySQL?
Istiaque Ahmed
Ya, kenapa tidak? Ada banyak referensi di dokumen: dev.mysql.com/doc/refman/5.7/en/…
Mosty Mostacho