นับด้วยเงื่อนไข 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
จะเกิดอะไรขึ้นถ้าคุณใช้ SUM แทน COUNT
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 = 'อนุมัติ') เป็นเคล็ดลับเฉพาะ MySQL
mojuba

1
@mojuba ไม่ 100% เหมือนกันผลตอบแทนเคล็ดลับของคุณnullเมื่อCOUNT(ไม่มีเงื่อนไข) 0จะได้กลับมา เมื่อCOUNTจะได้กลับมาอะไรแต่ 0 แต่SUM ไม่ return 0 0ผลตอบแทนเคล็ดลับของคุณ
Robin Kanters

@mojuba กรณีและจุด . num_relevant_partsเป็นSUMไปตามเงื่อนไขnum_total_partsคือCOUNT(parts.id)(ขออภัยสำหรับความคิดเห็นสองครั้งสายเกินไปที่จะแก้ไข)
Robin Kanters

68

ยังดีกว่า (หรือสั้นกว่าอยู่ดี):

SUM(ccc_news_comments.id = 'approved')

สิ่งนี้ใช้ได้ผลเนื่องจากประเภทบูลีนใน MySQL แสดงเป็นINT 0และ1เช่นเดียวกับใน C. (อาจไม่สามารถพกพาข้ามระบบ DB ได้)

ในฐานะที่เป็นCOALESCE()ที่กล่าวถึงในคำตอบอื่น ๆ , APIs หลายภาษาโดยอัตโนมัติแปลงNULLไป''เมื่อดึงค่า ยกตัวอย่างเช่นด้วย PHP ของอินเตอร์เฟซที่มันจะปลอดภัยที่จะเรียกใช้แบบสอบถามของคุณโดยไม่mysqliCOALESCE()


3
สิ่งนี้ทำให้โค้ด sql อ่านง่ายขึ้นอย่างมาก ทางออกที่สวยงาม
Dag Sondre Hansen

22

สิ่งนี้ควรใช้งานได้:

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

count()ตรวจสอบว่ามีค่าอยู่หรือไม่เท่านั้น 0 เทียบเท่ากับค่าที่มีอยู่ดังนั้นจึงนับอีกหนึ่งค่าในขณะที่ NULL เป็นเหมือนค่าที่ไม่มีอยู่จริงดังนั้นจึงไม่ถูกนับ


ฉันคิดว่าcountง่ายกว่าsumในกรณีนี้
Jeffery

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)) ??? ความหมายของการใช้ sum ถ้าคุณใช้ ccc_news_comments.id

ขอโทษคุณหมายถึงอะไร? ค่าบูลีนจะกลายเป็น 0 หรือ 1 จากนั้นจะรวมและในกรณีที่มีค่าว่างบางค่ารวมกันด้วย 0
Mosty Mostacho

@MostyMostacho COALESCEคืนผลรวมหรือไม่? มีการอ้างอิงในเอกสาร MySQL หรือไม่
Istiaque Ahmed

ใช่ทำไมจะไม่? มีข้อมูลอ้างอิงมากมายในเอกสาร: dev.mysql.com/doc/refman/5.7/en/…
Mosty Mostacho
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.