Zählen Sie mit der IF-Bedingung in der MySQL-Abfrage

114

Ich habe zwei Tabellen, eine für Nachrichten und eine für Kommentare, und ich möchte die Anzahl der Kommentare abrufen, deren Status als genehmigt festgelegt wurde.

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 

Das Problem bei dieser Abfrage ist jedoch, dass der Mindestwert, der für die Kommentarspalte abgerufen wird, 1 ist, unabhängig davon, ob ein Kommentar vorhanden ist, der dieser Nachricht entspricht oder nicht.

Jede Hilfe wäre sehr dankbar.

user1163513
quelle
5
Was ist, wenn Sie SUM anstelle von COUNT verwenden?
John Pick

Antworten:

264

Verwenden Sie sum()anstelle voncount()

Versuchen Sie es unten:

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
quelle
11
Oder sogar SUMME (ccc_news_comments.id = 'genehmigt') als MySQL-spezifischen Trick
Mojuba
1
@mojuba nicht 100% gleich, dein Trick kehrt zurück, nullwenn COUNT(keine Bedingungen) zurückgekehrt wäre 0. Wenn COUNThabe etwas zurück , aber 0, aber das SUM tut return 0, Ihr Trick zurückkehrt 0.
Robin Kanters
@mojuba Fall und Punkt . num_relevant_partsist SUMmit Bedingungen, num_total_partsist COUNT(parts.id)(Entschuldigung für doppelten Kommentar, war zu spät zum Bearbeiten)
Robin Kanters
68

Besser noch (oder sowieso kürzer):

SUM(ccc_news_comments.id = 'approved')

Dies funktioniert, da der Boolesche Typ in MySQL wie INT 0und 1in C dargestellt wird (möglicherweise nicht auf DB-Systemen portierbar).

Was COALESCE()wie in anderen Antworten erwähnt, konvertiert viele Sprechen APIs automatisch NULLauf , ''wenn der Wert abgerufen werden . Zum Beispiel wäre es mit der PHP- mysqliSchnittstelle sicher, Ihre Abfrage ohne auszuführen COALESCE().

Mojuba
quelle
3
Dies sorgt für deutlich besser lesbaren SQL-Code. Schöne Lösung.
Dag Sondre Hansen
22

Das sollte funktionieren:

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

count()Überprüfen Sie nur, ob der Wert vorhanden ist oder nicht. 0 entspricht einem vorhandenen Wert, zählt also einen weiteren, während NULL wie ein nicht vorhandener Wert ist und daher nicht gezählt wird.

Edemilson Lima
quelle
Ich denke countist intuitiver als sumin diesem Fall.
Jeffery
4

Ersetzen Sie diese Zeile:

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

Mit diesem:

coalesce(sum(ccc_news_comments.id = 'approved'), 0) comments
Mosty Mostacho
quelle
count (if (ccc_news_comments.id = 'genehmigt', ccc_news_comments.id, 0)) ??? Was bedeutet die Verwendung von Summe, wenn Sie ccc_news_comments.id
Entschuldigung, was meinst du? Der boolesche Wert wird 0 oder 1, dann summiert er sich und falls ein Nullwert mit 0 verschmilzt
Mosty Mostacho
@MostyMostacho, gibt COALESCEdie Summe zurück? Irgendeine Referenz in MySQL doc?
Istiaque Ahmed
Ja, warum sollte es nicht? Es gibt viele Referenzen in den Dokumenten: dev.mysql.com/doc/refman/5.7/en/…
Mosty Mostacho