unir - varios select en una consulta sql




consulta sql para devolver las diferencias entre dos tablas (7)

Esto hará el truco, similar con la solución de Tiago , la tabla de devolución de "fuente" también.

select [First name], [Last name], max(_tabloc) as _tabloc
from (
  select [First Name], [Last name], 't1' as _tabloc from table1
  union all
  select [First name], [Last name], 't2' as _tabloc from table2
) v
group by [Fist Name], [Last name]
having count(1)=1

El resultado contendrá diferencias entre tablas, en la columna _tabloc tendrá referencia de tabla.

Estoy tratando de comparar dos tablas, SQL Server, para verificar algunos datos. Quiero devolver todas las filas de ambas tablas donde los datos están en uno u otro. En esencia, quiero mostrar todas las discrepancias. Necesito verificar tres datos al hacerlo, FirstName, LastName y Product.

Soy bastante nuevo en SQL y parece que muchas de las soluciones que estoy encontrando están complicando las cosas. No tengo que preocuparme por NULLs.

Empecé probando algo como esto:

SELECT DISTINCT [First Name], [Last Name], [Product Name] FROM [Temp Test Data]
WHERE ([First Name] NOT IN (SELECT [First Name] 
FROM [Real Data]))

Sin embargo, estoy teniendo problemas para llevar esto más allá.

¡Gracias!

EDITAR:

Basado en la respuesta de @treaschf, he intentado usar una variación de la siguiente consulta:

SELECT td.[First Name], td.[Last Name], td.[Product Name]
FROM [Temp Test Data] td FULL OUTER JOIN [Data] AS d 
ON td.[First Name] = d.[First Name] AND td.[Last Name] = d.[Last Name] 
WHERE (d.[First Name] = NULL) AND (d.[Last Name] = NULL)

Pero sigo obteniendo 0 resultados, cuando sé que hay al menos 1 fila en td que no está en d.

EDITAR:

Ok, creo que lo descubrí. Al menos en mis pocos minutos de prueba, parece funcionar lo suficientemente bien.

SELECT [First Name], [Last Name]
FROM [Temp Test Data] AS td
WHERE (NOT EXISTS
        (SELECT [First Name], [Last Name]
         FROM [Data] AS d
         WHERE ([First Name] = td.[First Name]) OR ([Last Name] = td.[Last Name])))

Esto básicamente me dirá qué hay en mis datos de prueba que no está en mis datos reales. Lo cual está completamente bien para lo que tengo que hacer.


Hay un problema de rendimiento relacionado con la combinación izquierda, así como la unión completa con datos grandes.

En mi opinión, esta es la mejor solución:

select [First Name], count(1) e from (select * from [Temp Test Data] union all select * from [Temp Test Data 2]) a group by [First Name] having e = 1

Para una simple prueba de humo donde intentas asegurarte de que dos tablas coincidan sin preocuparte por los nombres de las columnas:

--ensure tables have matching records
Select count (*) from tbl_A
Select count (*) from tbl_B

--create temp table of all records in both tables
Select * into #demo from tbl_A 
Union All
Select * from tbl_B

--Distinct #demo records = Total #demo records/2 = Total tbl_A records = total tbl_B records
Select distinct * from #demo 

Puede escribir fácilmente un procedimiento de tienda para comparar un lote de tablas.


Prueba esto :

SELECT 
    [First Name], [Last Name]
FROM 
    [Temp Test Data] AS td EXCEPTION JOIN [Data] AS d ON 
         (d.[First Name] = td.[First Name] OR d.[Last Name] = td.[Last Name])

Mucho más simple de leer


SI tiene las tablas A y B , ambas con columna C , aquí están los registros, que están presentes en la tabla A pero no en B :

SELECT A.*
FROM A
    LEFT JOIN B ON (A.C = B.C)
WHERE B.C IS NULL

Para obtener todas las diferencias con una sola consulta, se debe usar una combinación completa, como esta:

SELECT A.*, B.*
FROM A
    FULL JOIN B ON (A.C = B.C)
WHERE A.C IS NULL OR B.C IS NULL

Lo que necesita saber en este caso es que cuando se puede encontrar un registro en A , pero no en B , las columnas que provienen de B serán NULL, y de manera similar para aquellas que están presentes en B y no en A , las columnas de A serán nulas.


Si desea obtener los valores de columna que son diferentes, puede usar el modelo Entidad-Atributo-Valor:

declare @Data1 xml, @Data2 xml

select @Data1 = 
(
    select * 
    from (select * from Test1 except select * from Test2) as a
    for xml raw('Data')
)

select @Data2 = 
(
    select * 
    from (select * from Test2 except select * from Test1) as a
    for xml raw('Data')
)

;with CTE1 as (
    select
        T.C.value('../@ID', 'bigint') as ID,
        T.C.value('local-name(.)', 'nvarchar(128)') as Name,
        T.C.value('.', 'nvarchar(max)') as Value
    from @Data1.nodes('Data/@*') as T(C)    
), CTE2 as (
    select
        T.C.value('../@ID', 'bigint') as ID,
        T.C.value('local-name(.)', 'nvarchar(128)') as Name,
        T.C.value('.', 'nvarchar(max)') as Value
    from @Data2.nodes('Data/@*') as T(C)     
)
select
    isnull(C1.ID, C2.ID) as ID, isnull(C1.Name, C2.Name) as Name, C1.Value as Value1, C2.Value as Value2
from CTE1 as C1
    full outer join CTE2 as C2 on C2.ID = C1.ID and C2.Name = C1.Name
where
not
(
    C1.Value is null and C2.Value is null or
    C1.Value is not null and C2.Value is not null and C1.Value = C2.Value
)

EJEMPLO DE FIDDLE SQL


(   SELECT * FROM table1
    EXCEPT
    SELECT * FROM table2)  
UNION ALL
(   SELECT * FROM table2
    EXCEPT
    SELECT * FROM table1) 




sql-server-2005