Подсчет с условием IF в запросе MySQL


116

У меня есть две таблицы, одна для новостей, а другая для комментариев, и я хочу получить количество комментариев, статус которых был установлен как одобренный.

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 

Но проблема с этим запросом заключается в том, что минимальное значение, которое выбирается для столбца комментариев, равно 1, независимо от того, существует ли какой-либо комментарий, соответствующий этой новости, или нет.

Любая помощь будет очень заметна.


5
Что делать, если вместо COUNT использовать SUM?
John Pick

Ответы:


267

Использовать sum()вместоcount()

Попробуйте ниже:

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
Или даже SUM (ccc_news_comments.id = 'authorized') как специфичный для MySQL трюк
mojuba

1
@mojuba не на 100% то же самое, ваш трюк возвращается, nullкогда COUNT(без условий) вернется 0. Когда COUNTбы я вернулся ничего , кроме 0, но SUM делает возврат 0, ваш трюк возвращается 0.
Робин Кантерс

@mojuba случай и точка . num_relevant_partsесть SUMс условиями, num_total_partsявляется COUNT(parts.id)(извините за двойной комментарий, было слишком поздно , чтобы редактировать)
Robin Кантеры

68

Еще лучше (или короче):

SUM(ccc_news_comments.id = 'approved')

Это работает, поскольку логический тип в MySQL представлен как INT 0и 1, как и в C. (хотя может не переноситься в системы БД).

Что касается, COALESCE()как упоминалось в других ответах, многие языковые API автоматически конвертируются NULLв ''при извлечении значения. Например, с mysqliинтерфейсом PHP было бы безопасно выполнять ваш запрос без COALESCE().


3
Это делает код sql значительно более читаемым. Красивое решение.
Даг Сондре Хансен

22

Это должно работать:

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

count()только проверьте, существует ли значение или нет. 0 эквивалентно существующему значению, поэтому он учитывает еще одно, в то время как NULL похож на несуществующее значение, поэтому не учитывается.


Я считаю countболее интуитивным, чем sumв этом случае.
Джеффри

4

Замените эту строку:

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

С этим:

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

количество (если (ccc_news_comments.id = 'утверждено', ccc_news_comments.id, 0)) ??? какой будет смысл использования суммы, если вы используете ccc_news_comments.id

Извини, что ты имеешь ввиду? Логическое значение становится 0 или 1, затем суммируется, и в случае слияния некоторого нулевого значения с 0
Mosty Mostacho

@MostyMostacho, COALESCEвозвращает ли сумму? Любая ссылка в документе MySQL?
Istiaque Ahmed

Да почему бы и нет? В документации много ссылок: dev.mysql.com/doc/refman/5.7/en/…
Мосты Мостачо
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.