我有以下查询:
SELECT s.username FROM `instagram_shop` s
INNER JOIN `instagram_shop_picture` p ON
s.id = p.shop_id
WHERE COUNT(p.id) = 0
GROUP BY p.id
;
我基本上想找到所有没有任何照片的商店。我想获得商店的用户名。但是上面的查询给了我#1111 - Invalid use of group function
为什么会这样?
以下是instagram_shop的样子:
这是instagram_shop_picture:
答案 0 :(得分:0)
WHERE
个过滤器(例如,聚合是GROUP BY或SUM()或AVG())。如果您需要在汇总后过滤结果,则需要使用HAVING
SELECT s.username, count(p.id)
FROM `instagram_shop` s
LEFT JOIN `instagram_shop_picture` p ON
s.id = p.shop_id
GROUP BY s.username
HAVING COUNT(p.id) = 0;
重要的是要注意HAVING
可能是一个昂贵的过程,因为数据库必须在使用之前返回并汇总所有结果。因此,如果您的返回结果是巨大的,HAVING
将会流失一段时间。
补充:正如大家所指出的那样,由于你的架构,你需要在这里使用LEFT JOIN。使用INNER JOIN会导致您从没有图片的结果中删除记录。一旦完成,在聚合之后OR之前将没有记录,其中count(p.id)= 0.所以你什么也得不回来。
查看您的架构,您也可以使用:
SELECT s.username
FROM `instagram_shop` s
LEFT JOIN (SELECT shop_id, count(id) as countOfPictures FROM `instagram_shop_picture`) p ON
s.id = p.shop_id
WHERE p.countOfPictures IS NULL
这可能实际上减少了运行时间,因为它涉及聚合来自单个表的较小结果(DB可以考虑索引)。派生表增加了一些开销,但总的来说你可能会提前出来。
答案 1 :(得分:0)
你有两件事要纠正。
HAVING
与聚合函数相关的条件
Where
用于在使用Count,Min,Max,Sum等聚合数据之前应用过滤器。
Having
,并且仅在聚合函数上使用。
使用LEFT OUTER JOIN
或EXISTS
当您使用Inner Join
时,您只会从instagram_shop和instagram_shop_picture获取行。要获取instagram_shop_picture中不存在的行,您可以使用OUTER JOIN
,或使用EXISTS
SELECT s.username
FROM instagram_shop s
LEFT OUTER JOIN instagram_shop_picture p
ON s.id = p.shop_id
GROUP BY p.id
HAVING COUNT(p.id) = 0
OR
SELECT s.username
FROM instagram_shop s
Where Not Exists
(
Select 1
From instagram_shop_picture p
Where s.id = p.shop_id
)
答案 2 :(得分:0)
尝试以下
Select *
From `instagram_shop` s Left Join `instagram_shop_picture` p On s.id = p.shop_id
Where p.shop_id is null