alter table postgresql
Cláusula NOT EXISTS en Postgresql (3)
¿Alguien sabe cómo realizar dicha consulta en Postgresql?
SELECT *
FROM tabA
WHERE NOT EXISTS (
SELECT *
FROM tabB
WHERE tabB.id = tabA.id
)
Cuando ejecuto dicha consulta, postgresql se queja " ERROR: Greenplum Database does not yet support that query
".
EDIT: y ¿qué hay de éste:
SELECT *
FROM tabA
WHERE NOT EXISTS (
SELECT *
FROM tabB WHERE tabB.id = tabA.id AND tabB.id2 = tabA.id2
)
EDITAR:
Probé en postgresql 8.2.15 para las 4 respuestas proporcionadas por @ypercube. Las conclusiones son:
1) El primero no funciona en esta versión de postgresql, como dije anteriormente en la pregunta. El mensaje de error se puede encontrar allí también.
2) Para las otras tres respuestas, la velocidad de ejecución es: (3) JUNTA IZQUIERDA> (4) EXCEPTO >> (2) NO EN.
Específicamente, para consultas que tienen la misma sintaxis, (3) LEFT JOIN toma alrededor de 5580ms, (4) EXCEPTO toma alrededor de 13502ms, y (2) NOT IN toma más de 100000 (De hecho, no esperé que terminara).
¿Hay alguna razón particular para que la cláusula NOT IN sea tan lenta?
Cheng
Hay 3 (principales) formas de hacer este tipo de consulta:
NOT EXISTS
subconsulta correlacionadaNOT IN
subconsultaLEFT JOIN
IS NULL
LEFT JOIN
conIS NULL
check:
Encontraste que la primera forma funciona en Greenplum. @Marco y @juergen proporcionaron la segunda vía. Aquí está el tercero, puede pasar por alto las limitaciones de Greenplum:
SELECT tabA.*
FROM
tabA
LEFT JOIN
tabB
ON tabB.id = tabA.id
AND tabB.id2 = tabA.id2
WHERE tabB.id IS NULL ;
Esto (4ª manera) también funciona en Postgres (que admite EXCEPT
operador):
SELECT a.*
FROM a
WHERE id IN
( SELECT id
FROM a
EXCEPT
SELECT id
FROM b
) ;
Probado en SQL-Fiddle (que los 4 funcionan en Postgres).
La parte del error que omitiste podría haberte apuntado en la dirección correcta. Creo que decía "DETALLE: la consulta contiene una subconsulta correlacionada". Por lo tanto, debe volver a escribirlos con uniones o subconsultas no correlacionadas.
SELECT * FROM tabA WHERE id NOT IN (SELECT id FROM tabB);
En cuanto a la segunda consulta, intente
SELECT * FROM tabA WHERE (id, id2) NOT IN (SELECT id, id2 FROM tabB);
SELECT * FROM tabA
WHERE id not in (SELECT id FROM tabB)