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.


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 

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().


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.


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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.