Policz z warunkiem JEŻELI w zapytaniu MySQL

116

Mam dwie tabele, jedną dla wiadomości, a drugą dla komentarzy i chcę uzyskać liczbę komentarzy, których status został ustawiony jako zatwierdzony.

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 

Ale problem z tym zapytaniem polega na tym, że minimalna wartość, która jest pobierana dla kolumny komentarzy, to 1, niezależnie od tego, czy istnieje komentarz odpowiadający tej wiadomości, czy nie.

Każda pomoc byłaby bardzo znacząca.

user1163513
źródło
5
A jeśli zamiast COUNT użyjesz SUMA?
John Pick

Odpowiedzi:

267

Użyj sum()zamiastcount()

Spróbuj poniżej:

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
źródło
11
Lub nawet SUMA (ccc_news_comments.id = 'Approved') jako sztuczka specyficzna dla MySQL
mojuba
1
@mojuba nie jest w 100% taka sama, twoja sztuczka powraca, nullgdy COUNT(żadne warunki) by nie zwróciły 0. Kiedy COUNTbędzie już wrócił nic ale 0, ale SUM robi return 0, swoje zyski podstęp 0.
Robin Kanters
@mojuba sprawa i punkt . num_relevant_partsjest SUMz warunkami, num_total_partsjest COUNT(parts.id)(przepraszam za podwójny komentarz, było za późno na edycję)
Robin Kanters
68

Jeszcze lepiej (lub krócej):

SUM(ccc_news_comments.id = 'approved')

Działa to, ponieważ typ boolowski w MySQL jest reprezentowany jako INT 0i 1, podobnie jak w C. (może jednak nie być przenośny między systemami DB).

Jak COALESCE()wspomniano w innych odpowiedziach, wiele interfejsów API języka automatycznie konwertuje się NULLna ''podczas pobierania wartości. Na przykład z mysqliinterfejsem PHP bezpieczne byłoby uruchomienie zapytania bez COALESCE().

mojuba
źródło
3
To sprawia, że ​​kod sql jest znacznie bardziej czytelny. Piękne rozwiązanie.
Dag Sondre Hansen
22

To powinno działać:

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

count()sprawdza tylko, czy wartość istnieje, czy nie. 0 jest równoważne istniejącej wartości, więc liczy się o jedną więcej, podczas gdy NULL jest jak nieistniejąca wartość, więc nie jest liczone.

Edemilson Lima
źródło
Myślę, że countjest bardziej intuicyjny niż sumw tym przypadku.
Jeffery,
4

Zastąp tę linię:

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

Z tym:

coalesce(sum(ccc_news_comments.id = 'approved'), 0) comments
Mosty Mostacho
źródło
count (if (ccc_news_comments.id = 'Approved', ccc_news_comments.id, 0)) ??? jakie będzie znaczenie użycia sumy, jeśli użyjesz ccc_news_comments.id
Przepraszam co masz na myśli? Wartość logiczna staje się 0 lub 1, a następnie suma, a na wypadek, gdyby była jakaś wartość zerowa, łączy się z 0
Mosty Mostacho
@MostyMostacho, czy COALESCEzwraca sumę? Wszelkie odniesienia w dokumencie MySQL?
Istiaque Ahmed
Tak, dlaczego nie? Dokumenty
Mosty Mostacho