将条件 aboutItem
从WHERE
子句移动到ON
子句。并将其更改COUNT(*)
为COUNT(Item.id)
:
SELECT
Area.id, Area.name, COUNT(Item.id) AS recentItems
FROM Area
LEFT JOIN Item_Area ON Area.id = Item_Area.areaId
LEFT JOIN Item ON Item.id = Item_Area.itemId
AND Item.published > DATE_SUB(NOW(), INTERVAL 10 DAY)
WHERE
Area.cityId = '1'
GROUP BY
Area.id
ORDER BY
Area.name ASC ;
请注意,上述内容不会在某些(严格)设置下运行,因为您Area.name
在SELECT
andORDER BY
列表中,而它不在GROUP BY
列表中。这取决于是否sql_mode
已设置为ONLY_FULL_GROUP_BY
。因此,将分组部分更改为:
GROUP BY
Area.id, Area.name
您还可以使用别名,使代码更具可读性(至少对很多人来说):
SELECT
a.id, a.name, COUNT(i.id) AS recentItems
FROM
Area AS a
LEFT JOIN
Item_Area AS ia ON a.id = ia.areaId
LEFT JOIN
Item AS i ON i.id = ia.itemId
AND i.published > DATE_SUB(NOW(), INTERVAL 10 DAY)
WHERE
a.cityId = '1'
GROUP BY
a.id
ORDER BY
a.name ASC ;
至少有两种更常见的写法。首先在派生表中分组,然后加入:
SELECT
a.id, a.name, COALESCE(g.recentItems, 0) AS recentItems
FROM
Area AS a
LEFT JOIN
( SELECT
ia.areaId, COUNT(*) AS recentItems
FROM
Item_Area AS ia
JOIN
Item AS i ON i.id = ia.itemId
WHERE
i.published > DATE_SUB(NOW(), INTERVAL 10 DAY)
GROUP BY
ia.areaId
) AS g ON a.id = g.areaId
WHERE
a.cityId = '1'
ORDER BY
a.name ASC ;
或使用内联子查询:
SELECT
a.id, a.name,
COALESCE(
( SELECT
COUNT(*)
FROM
Item_Area AS ia
JOIN
Item AS i ON i.id = ia.itemId
WHERE
i.published > DATE_SUB(NOW(), INTERVAL 10 DAY)
AND
a.id = ia.areaId
), 0
) AS recentItems
FROM
Area AS a
WHERE
a.cityId = '1'
ORDER BY
a.name ASC ;