118 votes

MySQL: utilisation non valide de la fonction group

Je suis de l'utilisation de MySQL. Voici mon schéma:

Fournisseurs(sid: integer, sname: chaîne, chaîne d'adresse)

Pièces(pid: integer, pname: string, couleur: string)

Catalogue(sid: integer, pid: entier, de coûts: réel)

(les clés primaires sont en gras)

Je suis en train d'écrire une requête pour sélectionner toutes les pièces qui sont prises 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, je suis même aller sur ce la bonne manière?

Deuxièmement, j'obtiens cette erreur:

1111 - Valide l'utilisation de la fonction de groupe

Ce que je fais mal?

Mise à jour: Cela fonctionne: (je suis pratiquement certain)

SELECT pid
FROM Catalog
GROUP BY pid
HAVING COUNT(sid) > 2

Regarde comme je n'ai même pas besoin d'une sous-requête.

197voto

rjh Points 17192

Vous devez utiliser HAVING et non WHERE.

La différence est la suivante: la clause WHERE filtre les lignes sélectionnées par MySQL. Ensuite, MySQL regroupe les lignes et agrège les nombres pour votre fonction COUNT.

HAVING est comme WHERE, cela ne se produit que lorsque la valeur COUNT a été calculée. Elle fonctionnera donc 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)
 

12voto

Mark Elliot Points 31871

Tout d'abord, l'erreur que vous obtenez est en raison de l'endroit où vous êtes à l'aide de l' COUNT fonction -- vous ne pouvez pas utiliser un agrégat (ou groupe) de la fonction dans l' WHERE de la clause.

Deuxièmement, au lieu d'utiliser une sous-requête, il vous suffit de rejoindre la table pour lui-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

Qui, je crois, doit retourner uniquement les lignes où au moins deux lignes existent avec le même pid mais il y a au moins 2 sids. Assurez-vous que vous obtenez en retour une seule ligne par pid j'ai appliqué une clause de groupement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X