MySQL没有使用Left Join和Group By返回0个聚合行

时间:2013-06-26 03:02:32

标签: mysql sql

我有以下查询。但是目前我正在努力让它通过聚合返回没有的行和数据。

我认为它可以与聚合和group by子句一起使用,所以如果有人可以expalin为什么那会很棒!

SELECT a.id, a.name, a.slug, COUNT(i.area_id) as numItems
FROM `area` `a`
LEFT JOIN `item` `i` ON a.id=i.area_id
WHERE i.date_expired > CURDATE() AND i.live = 1
GROUP BY `a`.`name`
ORDER BY `a`.`name`

由于

3 个答案:

答案 0 :(得分:1)

这是因为您在WHERE条件中引用了项目表,而该条目设置了OUTER JOIN。将其移至JOIN而不是:

SELECT a.id, a.name, a.slug, COUNT(i.area_id) as numItems
FROM `area` `a`
LEFT JOIN `item` `i` ON a.id=i.area_id
    AND i.date_expired > CURDATE() AND i.live = 1
GROUP BY `a`.`name`
ORDER BY `a`.`name`

答案 1 :(得分:1)

您应该过滤ON子句,因为您正在执行LEFT JOIN。例如

SELECT a.id, a.name, a.slug, COUNT(i.area_id) as numItems
FROM   area a
       LEFT JOIN item i 
          ON a.id = i.area_id AND
             i.date_expired > CURDATE() AND 
             i.live = 1
GROUP BY a.name
ORDER BY a.name

ON子句和WHERE子句的过滤之间的区别在于ON子句在表{I}}子句加入之前首先过滤记录从连接表的结果中过滤记录。

答案 2 :(得分:1)

问题是where子句撤消left join。当没有匹配时,i的所有字段的值都可以是NULL - 这些字段会被过滤掉,因为比较永远不会成立。

您可以通过将比较移至on子句来轻松解决此问题:

SELECT a.id, a.name, a.slug, COUNT(i.area_id) as numItems
FROM `area` `a`
LEFT JOIN `item` `i` ON a.id=i.area_id and
                        i.date_expired > CURDATE() AND i.live = 1
GROUP BY `a`.`name`
ORDER BY `a`.`name`