Ich benutze MySQL. Hier ist mein Schema:
Suppliers (sid: integer, sname: string, address string)
Teile (pid: integer, pname: string, farbe: string)
Katalog (sid: Ganzzahl, pid: Ganzzahl, Kosten: real)
(Primärschlüssel sind fett gedruckt)
Ich versuche eine Anfrage zu schreiben, um alle Teile auszuwählen, die von mindestens zwei Lieferanten hergestellt werden:
-- 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
);
Zuallererst, gehe ich das überhaupt richtig an?
Zweitens bekomme ich diesen Fehler:
1111 - Ungültige Verwendung der Gruppenfunktion
Was mache ich falsch?
Sie müssen HAVING
verwenden, nicht WHERE
.
Der Unterschied ist: Die WHERE
-Klausel filtert, welche Zeilen MySQL auswählt. Then MySQL gruppiert die Zeilen und aggregiert die Zahlen für Ihre COUNT
-Funktion.
HAVING
ist wie WHERE
, nur dass es passiert nach der COUNT
Wert wurde berechnet, so dass es wie erwartet funktioniert. Schreiben Sie Ihre Unterabfrage um als:
( -- 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)
Erstens ist der Fehler darauf zurückzuführen, wo Sie die Funktion COUNT
verwenden. Sie können in der Klausel WHERE
keine Aggregat- (oder Gruppen-) Funktion verwenden.
Zweitens, anstatt eine Unterabfrage zu verwenden, verbinden Sie einfach die Tabelle mit sich selbst:
SELECT a.pid
FROM Catalog as a LEFT JOIN Catalog as b USING( pid )
WHERE a.sid != b.sid
GROUP BY a.pid
Was ich glaube, sollte nur Zeilen zurückgeben, in denen mindestens zwei Zeilen mit dem gleichen pid
existieren, aber es gibt mindestens 2 sid
s. Um sicherzustellen, dass Sie nur eine Zeile pro pid
zurückerhalten, habe ich eine Gruppierungsklausel angewendet.