inner - SQL: ¿Cómo devolver filas de la tabla izquierda que no se encuentran en la tabla derecha?
inner join (7)
Esta página proporciona un desglose decente de los diferentes tipos de uniones, así como visualizaciones del diagrama de Venn para ayudar ... bueno ... visualizar la diferencia en las uniones.
Como dicen los comentarios, esta es una consulta bastante básica de los sonidos de la misma, así que debes tratar de entender las diferencias entre las uniones y lo que realmente significan.
Echa un vistazo a http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/
Estás buscando una consulta como:
DECLARE @table1 TABLE (test int)
DECLARE @table2 TABLE (test int)
INSERT INTO @table1
(
test
)
SELECT 1
UNION ALL SELECT 2
INSERT INTO @table2
(
test
)
SELECT 1
UNION ALL SELECT 3
-- Here''s the important part
SELECT a.*
FROM @table1 a
LEFT join @table2 b on a.test = b.test -- this will return all rows from a
WHERE b.test IS null -- this then excludes that which exist in both a and b
-- Returned results:
2
Tengo dos tablas con nombres de columna similares y necesito devolver registros de la tabla de la izquierda que no se encuentran en la tabla de la derecha. Tengo una clave principal (columna) que me ayudará a comparar ambas tablas. ¿Qué unión es la preferida?
Este es un ejemplo del trabajo de la vida real. Me pidieron que proporcionara una lista de usuarios que compraron en nuestro sitio en los últimos 6 meses, pero no en los últimos 3 meses.
Para mí, la forma más comprensible que puedo pensar es así:
--Users that bought from us 6 months ago and between 3 months ago.
DECLARE @6To3MonthsUsers table (UserID int,OrderDate datetime)
INSERT @6To3MonthsUsers
select u.ID,opd.OrderDate
from OrdersPaid opd
inner join Orders o
on opd.OrderID = o.ID
inner join Users u
on o.BuyerID = u.ID
where 1=1
and opd.OrderDate BETWEEN DATEADD(m,-6,GETDATE()) and DATEADD(m,-3,GETDATE())
--Users that bought from us in the last 3 months
DECLARE @Last3MonthsUsers table (UserID int,OrderDate datetime)
INSERT @Last3MonthsUsers
select u.ID,opd.OrderDate
from OrdersPaid opd
inner join Orders o
on opd.OrderID = o.ID
inner join Users u
on o.BuyerID = u.ID
where 1=1
and opd.OrderDate BETWEEN DATEADD(m,-3,GETDATE()) and GETDATE()
Ahora, con estas 2 tablas en mis manos, necesito obtener solo los usuarios de la tabla @ 6To3MonthsUsers que no están en la tabla @ Last3MonthsUsers .
Hay 2 maneras simples de lograrlo:
Usando Left Join:
select distinct a.UserID from @6To3MonthsUsers a left join @Last3MonthsUsers b on a.UserID = b.UserID where b.UserID is null
No en:
select distinct a.UserID from @6To3MonthsUsers a where a.UserID not in (select b.UserID from @Last3MonthsUsers b)
Ambas formas me darán el mismo resultado, yo personalmente prefiero la segunda porque es más legible.
No puedo agregar nada más que un ejemplo de código a las otras dos respuestas: sin embargo, encuentro que puede ser útil verlo en acción (las otras respuestas, en mi opinión, son mejores porque lo explican).
DECLARE @testLeft TABLE (ID INT, SomeValue VARCHAR(1))
DECLARE @testRight TABLE (ID INT, SomeOtherValue VARCHAR(1))
INSERT INTO @testLeft (ID, SomeValue) VALUES (1, ''A'')
INSERT INTO @testLeft (ID, SomeValue) VALUES (2, ''B'')
INSERT INTO @testLeft (ID, SomeValue) VALUES (3, ''C'')
INSERT INTO @testRight (ID, SomeOtherValue) VALUES (1, ''X'')
INSERT INTO @testRight (ID, SomeOtherValue) VALUES (3, ''Z'')
SELECT l.*
FROM
@testLeft l
LEFT JOIN
@testRight r ON
l.ID = r.ID
WHERE r.ID IS NULL
Prueba esto
SELECT f.*
FROM first_table f LEFT JOIN second_table s ON f.key=s.key
WHERE s.key is NULL
Para más información, lea este artículo: Uniones en el servidor SQL
Si está solicitando T-SQL, veamos primero los fundamentos. Hay tres tipos de uniones aquí, cada una con su propio conjunto de fases de procesamiento lógico como:
- Una
cross join
es la más simple de todas. Implementa solo una fase de procesamiento de consultas lógicas: unCartesian Product
. Esta fase opera en las dos tablas proporcionadas como entradas para la unión y produce un producto Cartesiano de las dos. Es decir, cada fila de una entrada coincide con todas las filas de la otra. Entonces, si tienes m filas en una tabla y n filas en la otra, obtienes m × n filas en el resultado. - Luego están
Inner joins
: aplican dos fases de procesamiento de consultas lógicas:A Cartesian product
entre las dos tablas de entrada como en una combinación cruzada, y luegofilters
filas según el predicado que especifique en la cláusulaON
(también conocida comoJoin condition
unión). - Luego viene el tercer tipo de combinaciones.
Outer Joins
outer join
: en unaouter join
, usted marca una tabla como una tablapreserved
usando las palabras claveLEFT OUTER JOIN
RIGHT OUTER JOIN
, oFULL OUTER JOIN
entre los nombres de la tabla. La palabra claveOUTER
esoptional
. La palabra claveLEFT
significa que las filas de laleft table
se conservan; la palabra claveRIGHT
significa que las filas en laright table
se conservan; y la palabra claveFULL
significa que las filas en las tablasleft
yright
se conservan. La tercera fase de procesamiento de consultas lógicas de unaouter join
identifica las filas de la tabla preservada que no encontraron coincidencias en la otra tabla en base al predicadoON
. Esta fase agrega esas filas a la tabla de resultados producida por las dos primeras fases de la unión, y usa marcasNULL
como marcadores de posición para los atributos del lado no preservado de la unión en esas filas externas.
Ahora, si nos fijamos en la pregunta: para devolver registros de la tabla de la izquierda que no se encuentran en la tabla de la derecha, use Left outer join
y filtre las filas con valores NULL
para los atributos del lado derecho de la combinación.
También me gusta usar NOT EXISTS. Cuando se trata de rendimiento, si el índice es correcto, debería tener el mismo rendimiento que un IZQUIERDA IZQUIERDA o mejor. Además es más fácil de leer.
SELECT Column1
FROM TableA a
WHERE NOT EXISTS ( SELECT Column1
FROM Tableb b
WHERE a.Column1 = b.Column1
)
seleccione * de la tabla izquierda donde no está el campo clave (seleccione el campo clave de la tabla derecha)