J'utilise MySQL. Voici mon schéma:
Fournisseurs (sid: integer, sname: string, address string)
Parties (pid: entier, pname: chaîne, couleur: chaîne)
Catalogue (sid: entier, pid: entier, coût: réel)
(les clés primaires sont en gras)
J'essaie d'écrire une requête pour sélectionner toutes les pièces fabriquées par au moins deux fournisseurs:
-- 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
);
Tout d'abord, est-ce que je vais même dans ce sens?
Deuxièmement, je reçois cette erreur:
1111 - Utilisation non valide de la fonction de groupe
Qu'est-ce que je fais mal?
Vous devez utiliser HAVING
et non pas WHERE
.
La différence est la suivante: la clause WHERE
filtre les lignes sélectionnées par MySQL. Then MySQL regroupe les lignes et agrège les nombres de votre fonction COUNT
.
HAVING
est comme WHERE
, seulement il arrive après la valeur COUNT
a été calculée, donc elle fonctionnera comme prévu. Réécrivez votre sous-requête en tant que:
( -- 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)
Premièrement, l'erreur que vous obtenez est due à l'utilisation de la fonction COUNT
. Vous ne pouvez pas utiliser une fonction d'agrégat (ou de groupe) dans la clause WHERE
.
Deuxièmement, au lieu d’utiliser une sous-requête, joignez simplement la table à elle-même:
SELECT a.pid
FROM Catalog as a LEFT JOIN Catalog as b USING( pid )
WHERE a.sid != b.sid
GROUP BY a.pid
Ce qui, à mon avis, ne devrait renvoyer que les lignes contenant au moins deux lignes avec le même pid
, mais au moins 2 sid
s. Pour vous assurer de ne récupérer qu'une ligne par pid
j'ai appliqué une clause de regroupement.