2010-07-15 13 views
7

Buscando la forma más fácil/más escalable de hacer una "diferencia" en SQL Server vea a continuación. alt textDiferencia SQL Server (opuesto a intersect)

Si no puede ver en la imagen, estoy buscando todo lo que no está en la intersección.

he visto una forma de hacerlo:

select * from (  
    (select 'test1' as a, 1 as b) 
union all 
    (select 'test2' as a , 2 as b union all select 'test1' as a , 1 as b) 
)un group by a,b having count(1)=1 

pero me temo que lo que sucedería si he utilizado dos conjuntos de gran tamaño (no voy a ser interrogación por Select '' declaraciones constantes, mis preguntas se tira de las tablas reales)

EDIT:.

Posible solución ...

drop table #temp_a; 
drop table #temp_b; 

go 


    select * into #temp_a from (
    select 1 as num, 'String' as two, 'int'as three, 'purple' as four union all 
    select 2 as num, 'dog' as two, 'int'as three, 'purple' as four union all 
    select 3 as num, 'dog' as two, 'int'as three, 'cat' as four) a 

select * into #temp_b from (
    select 1 as num, 'String' as two, 'decimal'as three, 'purple' as four union all 
    select 2 as num, 'dog' as two, 'int'as three, 'purple' as four union all 
    select 3 as num, 'dog' as two, 'int'as three, 'dog' as four) b 





    SELECT IsNull(a.num, b.num) A,IsNull(a.two, b.two) B, IsNull(a.three, b.three) C,     
     IsNull(a.four, b.four) D 
    FROM #temp_a a 
    FULL OUTER JOIN #temp_b b ON (a.num=b.num AND a.two=b.two and a.three=b.three and a.four=b.four) 
    WHERE (a.num is null or b.num is null ) 

RESULTADOS:

1 Cadena int púrpura

3 perro int gato

1 Cadena de diciembre púrpura

3 perro int perro

Respuesta

15

¿Qué tal algo como esto ?

SELECT A, B FROM Table1 EXCEPT SELECT A,B FROM Table2 
UNION 
SELECT A, B FROM Table2 EXCEPT SELECT A,B FROM Table1 

Aquí se muestra un ejemplo con el método FULL OUTER JOIN (suponiendo que A no es anulable en ambas tablas)

SELECT IsNull(Table1.A, Table2.A) a,IsNull(Table1.B, Table2.B) B 
FROM Table1 
FULL OUTER JOIN Table2 ON (Table1.A=Table2.A AND Table1.B=Table2.B) 
WHERE Table1.A is null or Table2.A is null 
+0

¿Qué la parte EsNulo lograr? ¿Es solo un medio para "mostrar" lo que falta? – Nix

+1

Para las filas que solo tienen un registro en una de las tablas (las que desea) habrá un nulo en una tabla u otra. Por ejemplo, Table1.A será nulo o Table2.A será nulo para cada fila. El Isnull toma el valor de cualquier lado que tenga un valor. – JohnFx

5

lo que está buscando se llama un Full Outer Join, which SQL Server supports.

+0

Inicialmente pensé algo así: select * from (seleccione 'test1' como a, 1 como b) One FULL JOIN (seleccione 'test2' como a, 2 como b union todos seleccione 'test1' como a, 1 como b) Dos \t ON One.a <> Two.a AND One.b <> Two.b Sin embargo, no es (ejecute ambos SQL) –

+1

sí, pero también debe filtrar todas las coincidencias después del join: 'WHERE keyA es NULL O keyB es NULL' –

+1

Una combinación externa completa NO es lo que la pregunta está pidiendo. Una combinación externa completa sería el Diagrama de Venn completamente completado, no solo las partes que no se intersectan del Diagrama de Venn. – Dogs

9

Alternativa:

SELECT A, B FROM Table1 UNION SELECT A,B FROM Table2 
EXCEPT 
SELECT A, B FROM Table2 INTERSECT SELECT A,B FROM Table1