2010-07-15 12 views
7

Cercare il modo più semplice e scalabile per eseguire una "differenza" di set in SQL Server, vedere di seguito. alt textDifferenza SQL Server (opposta all'intersezione)

Se non riesci a vedere dall'immagine, sto cercando tutto ciò che non si trova nell'intersezione.

ho visto un modo per farlo:

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 

ma temo che cosa accadrebbe se ho usato due grandi insiemi (io non sarò l'interrogazione da selezionare '' dichiarazioni costanti, le mie domande saranno tirando dalle tabelle reali)

EDIT:.

Possibile soluzione ...

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 ) 

RISULTATI:

1 String int viola

3 cane int gatto

1 Stringa dicembre viola

3 cane int cane

risposta

15

Che ne dite di qualcosa di simile ?

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

Ecco un esempio con la piena ESTERNO metodo join (supponendo che A non è annullabile in entrambe le tabelle)

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

Che cosa significa la parte IsNull raggiungere? E 'solo un mezzo per "mostrare" cosa manca? – Nix

+1

Per le righe che hanno solo un record in una delle tabelle (quelle che si desidera) ci sarà un nullo in una tabella o nell'altra. Ad esempio, Table1.A sarà null o Table2.A sarà null per ogni riga. Isnull prende il valore da qualsiasi parte ha un valore. – JohnFx

5

quello che stai dopo viene chiamato un Full Outer Join, which SQL Server supports.

+0

Inizialmente ho pensato qualcosa di simile: selezionare * da (selezionare 'test1' come a, 1 come b) Uno FULL JOIN (selezionare 'test2' come a, 2 come unione b tutti selezionano 'test1' come a, 1 as b) Two \t ON One.a <> Two.a AND One.b <> Two.b Tuttavia non è (esegui entrambi SQL) –

+1

sì, ma devi anche filtrare tutte le partite dopo il join: 'WHERE keyA is NULL O keyB is NULL' –

+1

Un join esterno completo NON è quello che la domanda sta chiedendo. Un'unione esterna completa sarebbe il diagramma di Venn completamente compilato, non solo le parti non intersecanti del diagramma di 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 
Problemi correlati