进行以下设置:
CREATE TABLE table1 (column1 text, column2 text);
CREATE TABLE table2 (column1 text, column2 text);
INSERT INTO table1 VALUES
('A', 'A')
, ('B', 'N')
, ('C', 'C')
, ('B', 'A');
INSERT INTO table2 VALUES
('A', 'A')
, ('B', 'N')
, ('C', 'X')
, ('B', 'Y');
如何在这两个表之间找到(column1, column2)
的 缺失组合 ?其他表中不匹配的行。
给定示例的预期结果将是:
C | C
B | A
C | X
B | Y
可能有重复的条目,因此我们想省略这些条目。
答案 0 :(得分:1)
您可以尝试对子查询使用not exists
,然后使用UNION ALL
select Column1,Column2 from table1 t1
where NOT exists
(
select 1
FROM table2 t2
where t1.Column1 = t2.Column1 or t1.Column2 = t2.Column2
)
UNION ALL
select Column1,Column2 from table2 t1
where NOT exists
(
select 1
FROM table1 t2
where t1.Column1 = t2.Column1 or t1.Column2 = t2.Column2
)
答案 1 :(得分:1)
一种方法是union all
:
select t1.col1, t1.col2
from t1
where (t1.col1, t1.col2) not in (select t2.col1, t2.col2 from t2)
union all
select t2.col1, t2.col2
from t2
where (t2.col1, t2.col2) not in (select t1.col1, t1.col2 from t1);
如果表中的中有重复项,则可以使用select distinct
将其删除。在表之间 没有重复的危险。
答案 2 :(得分:1)
您可以尝试设置操作。 EXCEPT
查找表中的行,而不查找另一行,UNION
将部分结果放入一个。
(SELECT column1,
column2
FROM table1
EXCEPT
SELECT column1,
column2
FROM table2)
UNION
(SELECT column1,
column2
FROM table2
EXCEPT
SELECT column1,
column2
FROM table1);
如果不需要重复消除,可以尝试使用ALL
变体(EXCEPT ALL
和UNION ALL
)。它们通常更快,因为DBMS不必查找并消除重复项。
答案 3 :(得分:1)
对于设置操作来说似乎是完美的任务:
( --all rows from table 1 missing in table 2
select *
from table1
except
select *
from table2
)
union all -- both select return distinct rows
( -- all rows in table 2 missing in table 1
select *
from table2
except
select *
from table1
)
答案 4 :(得分:1)
通过这个看似简单的任务,魔鬼在细节中。
简短而最快的:
SELECT col1, col2
FROM (SELECT col1, col2, TRUE AS x1 FROM t1) t1
FULL JOIN (SELECT col1, col2, TRUE AS x2 FROM t2) t2 USING (col1, col2)
WHERE (x1 AND x2) IS NULL;
FULL [OUTER] JOIN
包括两侧的所有行,但对于缺少的行的列填充NULL值。 WHERE
条件(x1 AND x2) IS NULL
标识这些不匹配的行。等效:WHERE x1 IS NULL OR x2 IS NULL
。
要消除重复对,请在末尾添加DISTINCT
(或GROUP BY
)-比 便宜骗子:
SELECT DISTINCT col1, col2
FROM ...
如果两边都有 许多 个重复对象,则在连接前折叠 会更便宜:
SELECT col1, col2
FROM (SELECT DISTINCT col1, col2, TRUE AS x1 FROM t1) t1
FULL JOIN (SELECT DISTINCT col1, col2, TRUE AS x2 FROM t2) t2 USING (col1, col2)
WHERE (x1 AND x2) IS NULL;
如果可以存在 NULL值,则更为复杂。 DISTINCT
/ DISTINCT ON
或GROUP BY
将它们视为相等(因此,具有NULL值的重复项将在上面的子查询中折叠)。但是JOIN
或WHERE
条件必须评估为TRUE
才能通过行。在这种情况下, 不 被认为是NULL值相等,FULL [OUTER] JOIN
从未找到包含NULL的对的匹配项。这可能是理想的,也可能不是理想的。您只需要了解差异并定义您的要求即可。
考虑在SQL Fiddle
中添加的演示 如果没有NULL值,没有重复项,但是在每个表中定义了NOT NULL
的附加列(如主键),让我们为每个id
命名,然后可以很简单:
SELECT col1, col2
FROM t1
FULL JOIN t2 USING (col1, col2)
WHERE t1.id IS NULL OR t2.id IS NULL;
相关: