2010-02-25 9 views
70

Estoy usando MySQL. Aquí está mi esquema:MySQL: uso no válido de la función de grupo

Proveedores (sid: enteros, Sname: cadena, cadena de dirección)

piezas (pid: enteros, pname: cuerda, color: String)

Catálogo (sid: entero, pid: entero, costo: bienes)

(claves primarias están en negrita)

soy t rying escribir una consulta para seleccionar todas las partes que están formadas por al menos dos proveedores:

-- 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 
); 

En primer lugar, ¿estoy incluso ir sobre esto de la manera correcta?

En segundo lugar, me sale este error:

1111 - Invalid use of group function

¿Qué estoy haciendo mal?

Respuesta

120

Debe usar HAVING, no DONDE.

La diferencia es: la cláusula WHERE filtra qué filas selecciona MySQL. Luego MySQL agrupa las filas y agrega los números para su función COUNT.

HAVING es como DONDE, solo ocurre después de el valor COUNT ha sido calculado, por lo que funcionará como usted espera. Vuelva a escribir su subconsulta como:

(     -- 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) 
+1

Entonces 'HAVING' cuenta primero y luego filtros, ¿verdad? –

+15

También si se usa GROUP BY, HAVING debe ser posterior a GROUP BY – Viacheslav

+0

Además, GROUP BY debe estar antes de HABER ... Debería haber leído el comentario de Bandolero: D – Andrew

4

Primero, el error que está recibiendo se debe a que está utilizando la función COUNT; no puede usar una función de agregado (o grupo) en la cláusula WHERE.

En segundo lugar, en vez de usar una sub consulta, sólo tiene que unirse a la tabla consigo misma:

SELECT a.pid 
FROM Catalog as a LEFT JOIN Catalog as b USING(pid) 
WHERE a.sid != b.sid 
GROUP BY a.pid 

que creo que debería devolver sólo las filas en las que existen al menos dos filas con el mismo pid pero hay al menos 2 sid s. Para asegurarse de obtener solo una fila por pid, he aplicado una cláusula de agrupación.

+0

¿Es posible que ni siquiera necesite una unión? (ver mi respuesta actualizada, donde proporcioné una posible solución.) –

+0

@Rosarch, creo que querrá usar 'COUNT (DISTINCT sid)' en su consulta actualizada. –

+0

No 'sid' siempre tiene que ser distinto de todos modos, porque' sid' y 'pid' juntos forman una clave primaria para' Catalog'? –

Cuestiones relacionadas