我的数据库中有两个表: 建议和投票
建议可以有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
但是,结果只显示了投票的建议!如果没有投票,我应该改变什么建议呢?
由于
答案 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