¿Cómo excluir filas que no se unen a otra tabla?

86

Tengo dos tablas, una tiene clave principal y la otra la tiene como clave externa.

Quiero extraer datos de la tabla principal, solo si la tabla secundaria no tiene una entrada que contenga su clave. Una especie de opuesto de una combinación interna simple, que devuelve solo filas que se unen mediante esa clave.

Chaddeus
fuente

Respuestas:

269

texto alternativo

SELECT <select_list> 
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
WHERE B.Key IS NULL

Imagen completa de unirse texto alternativo

Desde un artículo: http://www.codeproject.com/KB/database/Visual_SQL_Joins.aspx

Pranay Rana
fuente
9
¡finalmente! ¿Por qué no los tienen en los libros de texto y por qué mis profesores de la universidad no los tienen? usaron las peores explicaciones posibles del mundo, ¡ni remotamente cercanas a estas!
pythonian29033
4
Esto es oro. Odio escribir un comentario que no tiene más contenido que un elogio efusivo, ¡pero vamos! Esta es una respuesta asombrosa. Gracias, @Pranay Rana.
0xbe5077ed
1
Por favor, explícame, ¿por qué B.Key IS NULLpero todavía somos comparables A.Key = B.Key?
Do Nhu Vy
1
@DoNhuVy simple, la comparación está en la cláusula "ON", en una combinación IZQUIERDA o DERECHA si no hay una fila coincidente, se une una fila con todos los NULL, después de lo cual prueba IS NULL para saber que no hay una fila coincidente . (Esto solo funciona, por cierto, si el campo que está probando NO es NULL, es decir, no puede tener NULL por alguna otra razón)
Gregory Magarshak
Estoy usando la siguiente consulta: SELECT A. * FROM #PurgeFilesListNew A FULL OUTER JOIN #DoNotPurgeFilesListNew B ON A.JobFileId = B.JobFileId AND A.AccountID = B.AccountID DONDE A.JobFileId ES NULL O B.JobFileId ES NULO Y A.AccountID ES NULL O B.AccountID ES NULL Básicamente, tengo dos comparando dos valores en la cláusula "ON". Funciona bien, pero la consulta devuelve una fila nula para aquellas filas que no coinciden. ¿Cómo solucionar esto? Por favor ayuda
HarshSharma
10
SELECT
   *
FROM
   primarytable P
WHERE
   NOT EXISTS (SELECT * FROM secondarytable S
     WHERE
         P.PKCol = S.FKCol)

Generalmente , (NOT) EXISTSes una mejor opción entonces (NOT) INo(LEFT) JOIN

gbn
fuente
bueno, no publicó lo que se usa DBRMS, sin embargo, en MySql LEFT JOINsupera el rendimientoNOT EXIST
The Scrum Meister
@The Scrum Meister: ¿dije más rápido? Busque IN vs EXISTS vs JOIN para descubrir las diferencias semánticas y lógicas ...
gbn
@gbn Lo siento, pensé que con "mejor elección" te referías a más rápido. Entonces, ¿podría explicar de qué manera es una mejor opción? explainextended.com/2009/09/18/…
The Scrum Meister
1
@The Scrum Meister: en general, cualquier tipo de JOIN puede necesitar un DISTINCT. NOT IN con un nulo en la lista da falso. IN / EXISTS se comporta igual. Sin embargo, la única construcción "segura" es (NO) EXISTE a menos que le guste la inconsistencia
gbn
4

use una combinación izquierda "no existe":

SELECT p.*
FROM primary_table p LEFT JOIN second s ON p.ID = s.ID
WHERE s.ID IS NULL
El Scrum Meister
fuente
4

Otra solucion es:

SELECT * FROM TABLE1 WHERE id NOT IN (SELECT id FROM TABLE2)
Ali Akbar
fuente
3
SELECT P.*
FROM primary_table P
LEFT JOIN secondary_table S on P.id = S.p_id
WHERE S.p_id IS NULL
Tommi
fuente
2
Tengo una pregunta ... si usamos la condición P.key = S.keyy luego decimos where S.key IS NULL, ¿eso no hace que P.key también sea nula?
Somjit
2

Si desea seleccionar las columnas de la Primera tabla "que también están presentes en la Segunda tabla, en este caso también puede usar EXCEPT. En este caso, los nombres de las columnas también pueden ser diferentes, pero el tipo de datos debe ser el mismo".

Ejemplo:

select ID, FName
from FirstTable
EXCEPT
select ID, SName
from SecondTable
Anil Soman
fuente
0

Esto fue útil para usar en COGNOS porque se permitió la creación de una instrucción SQL "Not in" en Cognos, pero tardó demasiado en ejecutarse. Había codificado manualmente la tabla A para unirla a la tabla B en Cognos como A.key "no en" B.key, pero la consulta tardaba demasiado / no devolvía resultados después de 5 minutos.

Para cualquiera que esté buscando una solución "NOT IN" en Cognos, esto es lo que hice. Cree una consulta que combine las tablas A y B con LEFT JOIN en Cognos seleccionando el tipo de enlace: tabla A. La clave tiene valores de "0 a N" en la tabla B, luego agregó un filtro (estos corresponden a las cláusulas Where) para: tabla B .La clave es NULL.

Corrió rápido y como un encanto.

JennyB
fuente