LEFT JOIN即使是空SQL也是如此

时间:2015-02-20 12:23:58

标签: mysql sql

我的数据库中有两个表: 建议和投票

建议可以有0票或多票

我希望通过恶名来获得所有建议的验证顺序:

SELECT advices.*, COUNT(upvotes.id) - COUNT(downvotes.id) AS notoriety 
FROM `advices` 
LEFT JOIN votes AS upvotes ON upvotes.is_good=1 AND upvotes.advice_id=advices.id 
LEFT JOIN votes AS downvotes ON downvotes.is_good=0 AND downvotes.advice_id=advices.id 
WHERE `advices`.`subject_id` = 1
AND `advices`.`state` = 'validated' 
ORDER BY notoriety ASC

但是,结果只显示了投票的建议!如果没有投票,我应该改变什么建议呢?

由于

2 个答案:

答案 0 :(得分:2)

使用条件聚合而不是两个连接:

SELECT a.*, 
       (SUM(downvotes.is_good = 1) - SUM(downvotes.is_good = 0) ) AS notoriety 
FROM advices a LEFT JOIN
     votes v
     ON a.id = v.advice_id
WHERE a.`subject_id` = 1 AND a.`state` = 'validated' 
GROUP BY a.id
ORDER BY notoriety ASC;

您可以使用count(distinct)而不是count()来使用您的版本。但是,上述版本更简单,应该表现更好。

答案 1 :(得分:-2)

您遇到问题的原因是计数在没有投票的情况下返回null。您可以使用NVL函数将这些空值替换为0.

SELECT advices.*, nvl(COUNT(upvotes.id),0) - nvl(COUNT(downvotes.id),0) AS notoriety 
FROM `advices` 
LEFT JOIN votes AS upvotes ON upvotes.is_good=1 AND upvotes.advice_id=advices.id 
LEFT JOIN votes AS downvotes ON downvotes.is_good=0 AND downvotes.advice_id=advices.id 
WHERE `advices`.`subject_id` = 1
AND `advices`.`state` = 'validated' 
ORDER BY notoriety ASC