Порахуйте із умовою IF у запиті MySQL


115

У мене дві таблиці, одна - для новин, а інша - для коментарів, і я хочу отримати кількість коментарів, статус яких встановлено як затверджені.

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
Що робити, якщо ви використовуєте SUM замість COUNT?
Джон Пік

Відповіді:


265

Використання 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 = 'затверджений') як специфічний трюк для 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')

Це працює, оскільки тип Boole в 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 doc?
Істіаке Ахмед

Так, чому б і ні? У документах є багато посилань: dev.mysql.com/doc/refman/5.7/uk/…
Mosty Mostacho
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.