2017-01-06 6 views
1

Ich habe eine SQL-Abfrage, die Werte aus zwei Tabellen untereinander anzeigt. Jetzt möchte ich, dass die Tabelle die Werte aus den zwei verschiedenen Tabellen nebeneinander auswählt. Dies ist meine Frage jetzt:lassen Union Werte nebeneinander statt untereinander anzeigen

(select i1,i2 from t1 
except 
select i1,i2 from t2) 
union all 
(select i1,i2 from t2 
except 
select i1,i2 from t1) 

Das ist mein Beispieldaten:

Data I in Tabelle 1 haben:

i1 i2 
--------- 
| 1 | 1 | 
--------- 
| 2 | 2 | 
--------- 
| 2 | 3 | 
--------- 

Daten i in table2 haben:

i1 i2 
--------- 
| 1 | 1 | 
--------- 
| 2 | 3 | 
--------- 
| 2 | 4 | 
--------- 

Ergebnis:

--------- 
| 2 | 2 | << this one comes from table 1 
--------- 
| 2 | 4 | << this one comes from table 2 
--------- 

gewünschtes Ergebnis:

t1  t2 
----------------- 
| 2 | 2 | 2 | 4 | 
----------------- 
+3

, dass ein "Join" genannt wird. – mustaccio

+0

Das ist nicht der Zweck, oder wie eine Gewerkschaft funktioniert. Verwenden Sie einen Join mit einer NOT EXISTS-Klausel. – OldProgrammer

+0

okay, ich sehe, sorry Jungs sollte ich die Frage löschen? –

Antwort

0

Ich denke, der beste Weg, um eine WHERE mit den NULL Daten ein FULL JOIN und führen Sie dann zu verwenden wäre. Denn wenn Sie eine CROSS JOIN erstellen, erhalten Sie mehr Daten als Sie benötigen.

SELECT * 
FROM t1 
FULL JOIN t2 
    ON t1.i1 = 2.i1 
     AND t1.i2 = t2.i2 
WHERE t1.Id IS NULL 
    OR t2.Id IS NULL 

ich mit einem Beispiel erklären werde:

IF OBJECT_ID('tempdb..#t1') IS NOT NULL 
      DROP TABLE #t1 

CREATE TABLE #t1 
(
    Id INT IDENTITY, 
    i1 INT, 
    i2 INT 
) 

INSERT INTO #t1 
(
    i1,i2 
) 
VALUES 
(1,1) 
,(2,2) 
,(2,3) 
,(2,6) 

SELECT * FROM #t1 

IF OBJECT_ID('tempdb..#t2') IS NOT NULL 
      DROP TABLE #t2 

CREATE TABLE #t2 
(
    Id INT IDENTITY, 
    i1 INT, 
    i2 INT 
) 

INSERT INTO #t2 
(
    i1,i2 
) 
VALUES 
(1,1) 
,(2,3) 
,(2,4) 
,(2,5) 
,(2,7) 

SELECT * FROM #t2 


SELECT * 
FROM #t1 
FULL JOIN #t2 
    ON #t1.i1 = #t2.i1 
     AND #t1.i2 = #t2.i2 
WHERE #t1.Id IS NULL 
    OR #t2.Id IS NULL 

SELECT * 
FROM #t1 a 
CROSS JOIN #t2 b 
WHERE NOT EXISTS (SELECT 1 
        FROM #t2 c 
        WHERE a.i1 = c.i1 
        AND a.i2 = c.i2 
       ) 
    AND NOT EXISTS (SELECT 1 
        FROM #t1 c 
        WHERE b.i1 = c.i1 
        AND b.i2 = c.i2 
       ) 

RESULT

Im ersten Fall würden Sie 5 Datensätze erhalten, weil (2,2) und (2,6) existieren nicht in t2 und (2,4), (2,5), (2,7) existieren nicht in t1. Sie hätten also 5 Ergebnisse.

Allerdings würden Sie im CROSS JOIN 6 Ergebnisse erhalten, weil Sie ein kartesisches Produkt erstellen würden. 2 x 3 = 6 CROSS JOIN Explanation

Id   i1   i2   Id   i1   i2 
----------- ----------- ----------- ----------- ----------- ----------- 
2   2   2   3   2   4 
2   2   2   4   2   5 
2   2   2   5   2   7 
4   2   6   3   2   4 
4   2   6   4   2   5 
4   2   6   5   2   7 

(6 row(s) affected) 
+1

Ich dachte an einen vollen Join, aber um den '2,2' Record in die selbe Zeile wie der '2,4' Record zu bekommen, müßten Sie '<>' und 'OR' verwenden, und dann immernoch müssen unerwünschte Linien mit den 'NOT EXIST' filtern. –

+0

@HartCO Danke für Ihren Kommentar. Ich werde es prüfen! – JotaPardo

+0

@HartCO Ja, ich stimme dir zu. Ich habe den Benutzer gebeten, uns weitere Details zu geben, falls er zusätzliche Datensätze hinzufügen sollte. So kann ich besser sehen, was Sie wollen. – JotaPardo

0

Sie können dies eine mit tun CROSS JOIN und NOT EXISTS:

SELECT * 
FROM t1 a 
CROSS JOIN t2 b 
WHERE NOT EXISTS (SELECT 1 
        FROM t2 c 
        WHERE a.i1 = c.i1 
        AND a.i2 = c.i2 
       ) 
    AND NOT EXISTS (SELECT 1 
        FROM t1 c 
        WHERE b.i1 = c.i1 
        AND b.i2 = c.i2 
       ) 

A CROSS JOIN verbindet jeden Datensatz aus einer Tabelle mit jedem Datensatz von den anderen, so jede Kombination von Reihen ist zurück gekommen. NOT EXISTS wird angezeigt, um herauszufiltern Datensätze aus t1, die jemals in t2 und umgekehrt für die 2. NOT EXISTS

+0

Das würde mehr Datensätze als benötigt zurückgeben, wenn der Benutzer viel mehr Daten hat. Ich würde ein kartesisches Produkt machen, das der Benutzer nicht braucht. – JotaPardo

+0

Vielleicht unterschätzen Sie den Abfrageoptimierer, aber ich würde gerne eine Alternative sehen, die die gewünschte Ausgabe zurückgibt. –

0

versuchen

SELECT * 
FROM 
    (
     SELECT i1, i2 
     FROM t1 

     EXCEPT 

     SELECT i1, i2 
     FROM t2 
    ) a, 
    (
     SELECT i1, i2 
     FROM t2 

     EXCEPT 

     SELECT i1, i2 
     FROM t1 
    ) b 
+0

Es liefert das gleiche Ergebnis von CROSS JOIN, oder? – JotaPardo

+0

ja es wird sich kreuzen verbinden –

Verwandte Themen