Ik gebruik MySQL. Hier is mijn schema:
Leveranciers(sid: integer, sname: string, adresstring)
Parts(pid: geheel getal, pname: string, kleur: string)
Catalogus(sid: geheel getal, pid: geheel getal, kosten: reëel)
(primaire sleutels zijn vetgedrukt)
Ik probeer een query te schrijven om alle onderdelen te selecteren die door ten minste twee leveranciers zijn gemaakt:
-- 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
);
Ten eerste, doe ik dit wel op de juiste manier?
Ten tweede krijg ik deze foutmelding:
1111 – Ongeldig gebruik van groepsfunctie
Wat doe ik verkeerd?
Antwoord 1, autoriteit 100%
Je moet HAVING
gebruiken, niet WHERE
.
Het verschil is: de WHERE
-clausule filtert welke rijen MySQL selecteert. Vervolgensgroepeert MySQL de rijen en aggregeert de getallen voor uw functie COUNT
.
HAVING
is als WHERE
, alleen gebeurt het nadatde COUNT
waarde is berekend, dus het’ zal werken zoals u verwacht. Herschrijf uw subquery 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)
Antwoord 2, Autoriteit 6%
Eerste, de fout die u krijgt, is het gevolg van waar u de COUNT
-functie gebruiken – u kunt geen aggregate (of groeps) -functie gebruiken in de WHERE
Clausule.
Ten tweede, in plaats van een subquery te gebruiken, sluit u eenvoudig aan op de tabel:
SELECT a.pid
FROM Catalog as a LEFT JOIN Catalog as b USING( pid )
WHERE a.sid != b.sid
GROUP BY a.pid
waarvan ik denk dat we alleen rijen moeten retourneren waar ten minste twee rijen bestaan met dezelfde pid
, maar er is minimaal 2 sid
s. Om ervoor te zorgen dat u slechts één rij per pid
kent, heb ik een groepsclausule toegepast.