MySQL:无效使用组函数


104

我正在使用MySQL。这是我的架构:

供应商(sid:整数,sname:字符串,地址字符串)

零件(pid:整数,pname:字符串,color:字符串)

目录(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-无效使用组功能

我究竟做错了什么?

Answers:


173

您需要使用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)

25
同样,如果使用GROUP BY,则HAVING应该在GROUP BY之后
Viacheslav

1
另外,GROUP BY必须在还没开始之前就...。应该已经读过Bandolero的评论:D
Andrew

8

首先,您收到的错误是由于您使用COUNT函数的位置所致-您无法在WHERE子句中使用聚合(或组)函数。

其次,不要使用子查询,只需将表连接到自身即可:

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我应用了分组子句。


我什至不需要加入吗?(请参阅我提供的可能解决方案的最新答案。)
Nick Heiner 2010年

@Rosarch,我想您想COUNT(DISTINCT sid)在更新的查询中使用。
马克·艾略特

不一定sid总是必须与众不同,因为sidpid一起构成的主键Catalog
尼克·海纳尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.