Estoy tratando de comparar dos tablas para encontrar filas en cada tabla que no están en la otra. La Tabla 1 tiene una columna groupby para crear 2 conjuntos de datos dentro de la tabla uno.T-SQL - Uniones exteriores a la izquierda - Filtros en la cláusula where versus la cláusula on
groupby number
----------- -----------
1 1
1 2
2 1
2 2
2 4
La Tabla 2 tiene solo una columna.
number
-----------
1
3
4
Así Tabla 1 tiene los valores 1,2,4 en el grupo 2 y en la Tabla 2 tiene los valores 1,3,4.
espero que el siguiente resultado cuando se unen para el Grupo 2:
`Table 1 LEFT OUTER Join Table 2`
T1_Groupby T1_Number T2_Number
----------- ----------- -----------
2 2 NULL
`Table 2 LEFT OUTER Join Table 1`
T1_Groupby T1_Number T2_Number
----------- ----------- -----------
NULL NULL 3
La única manera que puedo conseguir que esto funcione es si pongo una cláusula donde por primera unirse a:
PRINT 'Table 1 LEFT OUTER Join Table 2, with WHERE clause'
select table1.groupby as [T1_Groupby],
table1.number as [T1_Number],
table2.number as [T2_Number]
from table1
LEFT OUTER join table2
--******************************
on table1.number = table2.number
--******************************
WHERE table1.groupby = 2
AND table2.number IS NULL
y un filtro en ON para el segundo:
PRINT 'Table 2 LEFT OUTER Join Table 1, with ON clause'
select table1.groupby as [T1_Groupby],
table1.number as [T1_Number],
table2.number as [T2_Number]
from table2
LEFT OUTER join table1
--******************************
on table2.number = table1.number
AND table1.groupby = 2
--******************************
WHERE table1.number IS NULL
¿Alguien puede encontrar una forma de no usar el filtro? en la cláusula on pero en la cláusula where
El contexto de esto es que tengo un área de ensayo en una base de datos y quiero identificar nuevos registros y registros que se han eliminado. El campo groupby es el equivalente de un batchid para un extracto y estoy comparando el último extracto en una tabla temporal con el lote de ayer almacenado en una tabla partioneds, que también tiene todos los lotes extraídos previamente. El código para crear la tabla 1 y 2:
create table table1 (number int, groupby int)
create table table2 (number int)
insert into table1 (number, groupby) values (1, 1)
insert into table1 (number, groupby) values (2, 1)
insert into table1 (number, groupby) values (1, 2)
insert into table2 (number) values (1)
insert into table1 (number, groupby) values (2, 2)
insert into table2 (number) values (3)
insert into table1 (number, groupby) values (4, 2)
insert into table2 (number) values (4)
EDIT:
Un poco más de contexto - dependiendo de donde pongo el filtro I resultados diferentes. Como se indicó anteriormente, la cláusula where me da el resultado correcto en un estado y el ON en el otro. Estoy buscando una manera consistente de hacer esto.
Dónde -
select table1.groupby as [T1_Groupby],
table1.number as [T1_Number],
table2.number as [T2_Number]
from table1
LEFT OUTER join table2
--******************************
on table1.number = table2.number
--******************************
WHERE table1.groupby = 2
AND table2.number IS NULL
Resultado:
T1_Groupby T1_Number T2_Number
----------- ----------- -----------
2 2 NULL
On -
select table1.groupby as [T1_Groupby],
table1.number as [T1_Number],
table2.number as [T2_Number]
from table1
LEFT OUTER join table2
--******************************
on table1.number = table2.number
AND table1.groupby = 2
--******************************
WHERE table2.number IS NULL
Resultado:
T1_Groupby T1_Number T2_Number
----------- ----------- -----------
1 1 NULL
2 2 NULL
1 2 NULL
Dónde (tabla 2 esta vez) -
select table1.groupby as [T1_Groupby],
table1.number as [T1_Number],
table2.number as [T2_Number]
from table2
LEFT OUTER join table1
--******************************
on table2.number = table1.number
AND table1.groupby = 2
--******************************
WHERE table1.number IS NULL
Resultado:
T1_Groupby T1_Number T2_Number
----------- ----------- -----------
NULL NULL 3
On -
select table1.groupby as [T1_Groupby],
table1.number as [T1_Number],
table2.number as [T2_Number]
from table2
LEFT OUTER join table1
--******************************
on table2.number = table1.number
--******************************
WHERE table1.number IS NULL
AND table1.groupby = 2
Resultado:
T1_Groupby T1_Number T2_Number
----------- ----------- -----------
(0) rows returned
¿Por qué es importante mover la condición de la cláusula 'JOIN' a la cláusula' WHERE'? Poner predicados en 'JOIN' es algo normal cuando quieres este tipo de comportamiento. – Aaronaught
Moverlo a la cláusula where no es tan importante como el hecho de que para la primera unión donde uní la tabla 1 a la tabla 2 obtengo un resultado diferente si coloco el filtro en "on" y no en "where". PRINT 'Tabla 1 LEFT OUTER JOIN Tabla 2, la cláusula WHERE' seleccionar \t table1.groupby como [T1_Groupby], \t \t table1.number como [T1_Number], \t \t table2.number como [T2_Number] de \t tabla1 \t \t combinación externa izquierda tabla2 \t \t \t - ****************************** \t \t \t en table1.number = table2.number \t \t \t Y table1.groupby = 2 \t \t \t - ****************************** DONDE \t --table1 .groupby = 2 AND \t table2.number IS NULL Da nulo solo –
Bueno, ¿cuál quieres? Parece que la unión NULL hace lo que quieres decir. Esta es una forma estándar de hacer consultas como esta y generalmente es preferible a las alternativas de subconsulta. No veo ningún beneficio al intentar impulsar la condición en una cláusula WHERE. – bobince