让工会显示彼此相邻的价值而不是彼此之下

时间:2017-01-06 16:41:51

标签: sql sql-server

我得到一个SQL查询,它显示两个表之下的值。现在我希望表格从两个不同的表格中选择除了彼此之外的值。这是我现在的问题:

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

这是我的样本数据:

表1中的数据:

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

我在表2中的数据:

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

结果:

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

想要的结果:

   t1      t2
-----------------
| 2 | 2 | 2 | 4 |
-----------------

3 个答案:

答案 0 :(得分:1)

我认为最好的方法是使用FULL JOIN,然后使用WHERE数据执行NULL。因为如果你制作一个CROSS JOIN,你会获得比你需要的更多的数据。

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

我将用一个例子来解释:

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

在第一种情况下,你将获得5条记录,因为(2,2)和(2,6)在t2中不存在,而(2,4),(2,5),(2,7)不存在存在于t1中。所以你会得到5个结果。

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

(5 row(s) affected)

但是,在CROSS JOIN中你会获得6个结果,因为你会制作一个笛卡尔积。 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 :(得分:0)

您可以使用CROSS JOINNOT 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
                  )

CROSS JOIN将来自一个表的每个记录与来自另一个表的每个记录连接起来,因此返回每个行的组合。 NOT EXISTS用于过滤掉t1t2出现的记录,反之亦然NOT EXISTS

答案 2 :(得分:0)

尝试

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