我正在使用MySQL。这是我的架构:
供应商( sid:整数,sname:字符串,地址字符串)
零件( pid:整数,pname:string,color:string)
目录( sid:整数,pid:整数,成本:真实)
(主键以粗体显示)
我正在尝试编写一个查询来选择至少由两家供应商制作的所有零件:
-- Find the pids of parts supplied by at least two different suppliers.
SELECT c1.pid -- select the pid
FROM Catalog AS c1 -- from the Catalog table
WHERE c1.pid IN ( -- where that pid is in the set:
SELECT c2.pid -- of pids
FROM Catalog AS c2 -- from catalog
WHERE c2.pid = c1.pid AND COUNT(c2.sid) >= 2 -- where there are at least two corresponding sids
);
首先,我是否正确地采取了这种方式?
其次,我收到了这个错误:
1111 - 无效使用群组功能
我做错了什么?
答案 0 :(得分:149)
您需要使用HAVING
,而不是WHERE
。
区别在于:WHERE
子句过滤MySQL选择的行。 然后 MySQL将行组合在一起并聚合COUNT
函数的数字。
HAVING
与WHERE
类似,只有在计算出COUNT
值后才会发生,因此它会按预期工作。将子查询重写为:
( -- where that pid is in the set:
SELECT c2.pid -- of pids
FROM Catalog AS c2 -- from catalog
WHERE c2.pid = c1.pid
HAVING COUNT(c2.sid) >= 2)
答案 1 :(得分:8)
首先,您获得的错误是由于您使用COUNT
函数的位置 - 您不能在WHERE
子句中使用聚合(或组)函数。 / p>
其次,不要使用子查询,只需将表连接到自身:
SELECT a.pid
FROM Catalog as a LEFT JOIN Catalog as b USING( pid )
WHERE a.sid != b.sid
GROUP BY a.pid
我认为应该只返回至少有两行存在且具有相同pid
但至少有2 sid
秒的行。为了确保每个pid
只返回一行,我已经应用了一个分组条款。