我正在尝试为给定的城市ID选择所有区域。 另外,我正在计算COUNT(*)以查看每个区域存在多少个项目。 由于Items通过manyToMany关系与Areas相关,因此JOIN必须通过名为Item_Area的相应JOIN表进行。
不幸的是,我只获得了实际拥有近期物品的区域 - 但我想要所有区域。如果没有,最近的项目应该简单为零。我认为问题与发布日期的WHERE条件有关 - 但我无法弄清楚如何使其正常工作。
如何修改以下查询,为给定的Area.cityId选择所有区域 - 并简单地计算“recentItems”= 0,对于没有最近项目的区域(即不匹配)对Item.published字段的限制是在过去10天内。
SELECT
`Area`.`id`, `Area`.`name`, COUNT(*) AS `recentItems`
FROM `Area`
LEFT JOIN `Item_Area` ON `Area`.`id` = `Item_Area`.`areaId`
LEFT JOIN `Item` ON `Item`.`id` = `Item_Area`.`itemId`
WHERE
`Area`.`cityId` = "1" AND
Item.published > DATE_SUB(NOW(), INTERVAL 10 DAY) GROUP BY `Area`.`id`
ORDER BY `Area`.`name` ASC
答案 0 :(得分:1)
将Item
子句中的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
列表中的ORDER 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 ;
答案 1 :(得分:0)
Item.published上的过滤条件限制数据可用于具有项目条目的区域。由于您需要没有项目的区域,您需要插入条件Item.published> DATE_SUB(NOW(),INTERVAL 10 DAY)加入。
SELECT
`Area`.`id`, `Area`.`name`, COUNT(1) AS `recentItems`
FROM `Area`
LEFT JOIN `Item_Area` ON `Area`.`id` = `Item_Area`.`areaId`
LEFT JOIN `Item` ON `Item`.`id` = `Item_Area`.`itemId` and
WHERE
`Area`.`cityId` = "1"
GROUP BY `Area`.`id`
ORDER BY `Area`.`name` ASC