Conta con la condizione IF nella query MySQL


115

Ho due tabelle, una per le notizie e l'altra per i commenti e desidero ottenere il conteggio dei commenti il ​​cui stato è stato impostato come approvato.

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 

Ma il problema con questa query è che il valore minimo che viene recuperato per la colonna dei commenti è 1 indipendentemente dal fatto che vi siano commenti esistenti corrispondenti a quella notizia o meno.

Qualsiasi aiuto sarebbe molto apprezzabile.


5
E se usi SUM invece di COUNT?
John Pick

Risposte:


265

Utilizzare sum()al posto dicount()

Prova di seguito:

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 

11
O anche SUM (ccc_news_comments.id = 'approvato') come trucco specifico per MySQL
mojuba

1
@mojuba non è uguale al 100%, il tuo trucco ritorna nullquando COUNT(nessuna condizione) sarebbe tornato 0. Quando COUNTsarei tornato nulla ma 0, ma la SUM fa ritorno 0, le vostre dichiarazioni trucco 0.
Robin Kanters

@mojuba caso e punto . num_relevant_partsè SUMcon le condizioni, num_total_partsè COUNT(parts.id)(scusa per il doppio commento, era troppo tardi per la modifica)
Robin Kanters

68

Meglio ancora (o comunque più breve):

SUM(ccc_news_comments.id = 'approved')

Questo funziona poiché il tipo booleano in MySQL è rappresentato come INT 0e 1, proprio come in C. (Potrebbe non essere portabile tra i sistemi DB).

Per quanto riguarda COALESCE()come detto in altre risposte, molte API lingua convertono automaticamente NULLa ''quando va a prendere il valore. Ad esempio con l' mysqliinterfaccia di PHP sarebbe sicuro eseguire la query senza COALESCE().


3
Ciò rende il codice sql molto più leggibile. Bella soluzione.
Dag Sondre Hansen

22

Questo dovrebbe funzionare:

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

count()controlla solo se il valore esiste o meno. 0 è equivalente a un valore esistente, quindi ne conta uno in più, mentre NULL è come un valore inesistente, quindi non viene conteggiato.


Penso che countsia più intuitivo che sumin questo caso.
Jeffery

4

Sostituisci questa riga:

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

Con questo:

coalesce(sum(ccc_news_comments.id = 'approved'), 0) comments

count (if (ccc_news_comments.id = 'approvato', ccc_news_comments.id, 0)) ??? quale sarà il significato dell'utilizzo di sum se utilizzi ccc_news_comments.id

Scusa, cosa intendi? Il valore booleano diventa 0 o 1, quindi somma, e nel caso in cui ci sia un valore nullo si fonde con 0
Mosty Mostacho

@MostyMostacho, COALESCErestituisce la somma? Qualche riferimento nel documento MySQL?
Istiaque Ahmed

Sì, perché non dovrebbe? Ci sono molti riferimenti nei documenti: dev.mysql.com/doc/refman/5.7/en/…
Mosty Mostacho
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.