2010-02-25 30 views
70

我正在使用MySQL。這裏是我的架構:MySQL:無法使用組功能

供應商(SID:整數,SNAME:字符串,地址字符串)

零件(PID:整數,PNAME:字符串,顏色:字符串)

目錄( SID:整數,PID:整數,成本:實數)

(主鍵以粗體顯示)

我噸rying編寫一個查詢來選擇由至少兩家供應商的所有部分:

-- 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 - Invalid use of group function

我在做什麼錯?

回答

120

您需要使用HAVING,而不是WHERE。

區別在於:WHERE子句過濾MySQL選擇的行。 然後 MySQL將這些行分組在一起並彙總COUNT函數的數字。

HAVING就像在哪裏,只有在之後發生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

所以'HAVING'先計算過濾器,是嗎? – 2013-07-17 07:29:11

+15

另外,如果使用GROUP BY,HAVING應該在GROUP BY – Viacheslav 2014-06-22 17:40:34

+0

之後。此外,GROUP BY需要在HAVING之前....應該閱讀Bandolero的評論:D – Andrew 2014-12-16 16:52:58

4

首先,您得到的錯誤是由於您使用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 s。爲確保您每回pid只收回一行,我已經應用了分組子句。

+0

是否有可能我甚至不需要連接? (請參閱我的更新答案,我提供了一個可能的解決方案。) – 2010-02-25 01:03:50

+0

@Rosarch,我認爲您希望在更新後的查詢中使用COUNT(DISTINCT sid)。 – 2010-02-25 01:04:41

+0

因爲'sid'和'pid'一起構成'Catalog'的主鍵,所以'sid'總是不得不分開嗎? – 2010-02-25 01:07:48