我正在尝试查找表A中存在但不在表B中的记录。如果只有一列要检查,那么我可以使用
select col_A,col_B,......from A where col_A not in (select Col_A from B).
但我有四列需要检查。
我做了类似这样的事情,虽然有效但不是完美的方式
select col_A,col_B,col_C,col_D from A where col_A||col_B||col_C||col_D not in (select col_A||col_B||col_C||col_D from B)
并且在大量数据的情况下返回结果也需要很多时间。
请建议正确的方法。
感谢.....
答案 0 :(得分:5)
来自Oracle文档
http://docs.oracle.com/cd/E11882_01/server.112/e26088/queries004.htm#SQLRF52341
“MINUS示例以下语句将结果与MINUS运算符组合在一起,后者仅返回第一个查询返回的唯一行,但不返回第二个查询:”
SELECT product_id FROM inventories
MINUS
SELECT product_id FROM order_items;
您的要求有点复杂。我假设,cols_a,cols_b,cols_c,cols_d的组合对于表A中的记录是唯一的。在这种情况下,以下代码应该可以解决您的问题:
create table A (
cols_date DATE,
cols_a NUMBER,
cols_b NUMBER,
cols_c NUMBER,
cols_d NUMBER
);
create table B (
cols_a NUMBER,
cols_b NUMBER,
cols_c NUMBER,
cols_d NUMBER
);
insert into A (cols_date, cols_a, cols_b, cols_c, cols_d) values (sysdate, 1, 1, 1, 1);
insert into A (cols_date, cols_a, cols_b, cols_c, cols_d) values (sysdate, 2, 2, 2, 2);
insert into B (cols_a, cols_b, cols_c, cols_d) values (2, 2, 2, 2);
insert into B (cols_a, cols_b, cols_c, cols_d) values (3, 3, 3, 3);
commit;
select a.cols_date, a.cols_a, a.cols_b, a.cols_c, a.cols_d from (
select cols_a, cols_b, cols_c, cols_d
from A
minus
select cols_a, cols_b, cols_c, cols_d
from b
) ma, a
where 1=1
and ma.cols_a = a.cols_a
and ma.cols_b = a.cols_b
and ma.cols_c = a.cols_c
and ma.cols_d = a.cols_d;
结果是
COLS_DATE COLS_A COLS_B COLS_C COLS_D
--------------------- ---------- ---------- ---------- ----------
01.07.2013 13:20:02 1 1 1 1
NOT EXISTS也将解决问题。该语句具有比MINUS版本更好的执行计划。
感谢David Aldridge提供此解决方案。
select
cols_date,
cols_a, cols_b, cols_c, cols_d
from
a
where
not exists (
select 1
from b
where 1=1
and b.cols_a = a.cols_a
and b.cols_b = a.cols_b
and b.cols_c = a.cols_c
and b.cols_d = a.cols_d
);
答案 1 :(得分:3)
你可能想避免在MINUS上隐含明显的区别。
NOT EXISTS构造可能会作为哈希反连接运行,这将非常有效。
select
col1,
col2,
col3,
... etc
from
table_a a
where
not exists (
select null
from table_b b
where a.col1 = b.col1 and
a.col2 = b.col2 and
a.col3 = b.col3 and
a.col4 = b.col4)
答案 2 :(得分:1)
WITH mine AS (
SELECT cols_a, cols_b, cols_c, cols_d FROM a
MINUS
SELECT cols_a, cols_b, cols_c, cols_d FROM b
)
SELECT a.cols_date, a.cols_a, a.cols_b, a.cols_c, a.cols_d
FROM a NATURAL JOIN mine