web-dev-qa-db-fra.com

MySQL: utilisation non valide de la fonction group

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?

88
Nick Heiner

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)
151
rjh

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 sids. Pour vous assurer de ne récupérer qu'une ligne par pid j'ai appliqué une clause de regroupement.

8
Mark Elliot