Đếm với điều kiện IF trong truy vấn MySQL


115

Tôi có hai bảng, một bảng dành cho tin tức và bảng còn lại dành cho nhận xét và tôi muốn tính số lượng nhận xét có trạng thái đã được đặt là đã được phê duyệt.

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 

Nhưng vấn đề với truy vấn này là giá trị tối thiểu được tìm nạp cho cột nhận xét là 1 liệu có tồn tại bất kỳ bình luận nào tương ứng với tin tức đó hay không.

Bất kỳ sự giúp đỡ sẽ được đánh giá cao.


5
Điều gì sẽ xảy ra nếu bạn sử dụng SUM thay vì COUNT?
John Pick

Câu trả lời:


265

Sử dụng sum()thay chocount()

Hãy thử bên dưới:

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
Hoặc thậm chí SUM (ccc_news_comments.id = 'chấp nhận') như là một MySQL cụ thể lừa
mojuba

1
@mojuba không giống 100%, thủ thuật của bạn sẽ quay trở lại nullkhi COUNT(không có điều kiện) quay trở lại 0. Khi COUNTnào trả về bất cứ thứ gì ngoại trừ 0, nhưng SUM không trả về 0, thủ thuật của bạn sẽ trả về 0.
Robin Kanters

@mojuba trường hợp và điểm . num_relevant_partsSUMvới các điều kiện, num_total_partsCOUNT(parts.id)(xin lỗi vì đã nhận xét kép, đã quá muộn để chỉnh sửa)
Robin Kanters

68

Vẫn tốt hơn (hoặc ngắn hơn dù sao):

SUM(ccc_news_comments.id = 'approved')

Điều này hoạt động vì kiểu Boolean trong MySQL được biểu diễn dưới dạng INT 01, giống như trong C. (Tuy nhiên, có thể không di động trên các hệ thống DB.)

Như COALESCE()đã đề cập trong các câu trả lời khác, nhiều API ngôn ngữ tự động chuyển đổi NULLthành ''khi tìm nạp giá trị. Ví dụ với mysqligiao diện của PHP, sẽ an toàn nếu không có truy vấn của bạn COALESCE().


3
Điều này làm cho mã sql dễ đọc hơn đáng kể. Giải pháp đẹp.
Dag Sondre Hansen

22

Điều này sẽ hoạt động:

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

count()chỉ kiểm tra xem giá trị có tồn tại hay không. 0 tương đương với một giá trị tồn tại, vì vậy nó sẽ đếm một giá trị nữa, trong khi NULL giống như một giá trị không tồn tại, vì vậy nó không được tính.


Tôi nghĩ countlà trực quan hơn sumtrong trường hợp này.
Jeffery,

4

Thay thế dòng này:

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

Với cái này:

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

đếm (nếu (ccc_news_comments.id = 'được chấp thuận', ccc_news_comments.id, 0)) ??? những gì sẽ được nghĩa của việc sử dụng số tiền nếu bạn sử dụng ccc_news_comments.id

Xin lỗi, ý bạn là gì? Giá trị boolean trở thành 0 hoặc 1, sau đó tổng hợp, và trong trường hợp có một số liên hiệp với giá trị null 0
Mosty Mostacho

@MostyMostacho, có COALESCEtrả về tổng không? Bất kỳ tài liệu tham khảo trong MySQL?
Istiaque Ahmed

Có, tại sao lại không? Có rất nhiều tài liệu tham khảo trong các tài liệu: dev.mysql.com/doc/refman/5.7/en/...
Mosty Mostacho
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.