我正在尝试构造一个具有以下特性的查询:如果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)
但我认为我的语法不正确。关于如何解决这个问题的任何建议都将非常受欢迎。
答案 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来删除重复项。