多个联合语句和结果表的差异

时间:2013-05-10 10:05:09

标签: mysql sql union

我正在尝试构造一个具有以下特性的查询:如果x在A和B的并集中,但不在C和D的并集中,则返回x

例如:

table    table    table    table
+---+    +---+    +---+    +---+
| A |    | B |    | C |    | D |
+---+    +---+    +---+    +---+
| 1 |    | 4 |    | 2 |    | 3 |
| 2 |    | 5 |    | 3 |    | 7 |
| 3 |    | 6 |    +---+    +---+
| 4 |    | 7 |
+---+    +---+

我会寻找这个回报:

+---+
| E |
+---+
| 1 |
| 4 |
| 5 |
| 6 |
+---+

我试过了:

SELECT * from A
union
SELECT * from B
WHERE * not in
(SELECT * from C
union
SELECT * from D)

但我认为我的语法不正确。关于如何解决这个问题的任何建议都将非常受欢迎。

3 个答案:

答案 0 :(得分:2)

试试这个:

SELECT u1.col1
FROM (SELECT col1 from A union SELECT col1 from B) u1
LEFT OUTER JOIN (SELECT col1 from C union SELECT col1 from D) u2
ON u1.col1 = u2.col1
WHERE u2.col1 IS NULL

请参阅SQLFiddle上的演示。

查询执行两个联合结果的左外连接,然后过滤掉其中一个联合结果中缺少的联接结果。

答案 1 :(得分:1)

'union'命令是一个查询分隔符。这意味着它之前的内容是一个查询,而后面的内容是另一个查询。因此,WHERE子句仅适用于第二个查询(来自B的SELECT *)。

根据您的SQL平台,您可以将WHERE子句复制到UNION之前,以便它适用于两个查询。或者,您可能需要使用JOIN或EXCEPTION JOIN或EXISTS,以获得您想要的效果。

答案 2 :(得分:1)

我会这样写你的查询:

SELECT *
FROM A
WHERE A.ID NOT IN (SELECT ID FROM C)
      AND A.ID NOT IN (SELECT ID FROM D)
UNION
SELECT *
FROM B
WHERE B.ID NOT IN (SELECT ID FROM C)
      AND B.ID NOT IN (SELECT ID FROM D)

您也可以这样写:

SELECT *
FROM
  (SELECT * FROM A UNION SELECT * FROM B) s
WHERE
  ID NOT IN (SELECT ID FROM C UNION SELECT ID FROM D)

请参阅小提琴here。您可能希望使用UNION ALL而不是UNION来删除重复项。