3

我正在尝试查找表 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)

并且在大量数据的情况下返回结果需要大量时间。

请建议这样做的正确方法。

谢谢.....

4

3 回答 3

6

来自 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           
);
于 2013-07-01T08:45:30.133 回答
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)
于 2013-07-01T13:58:02.537 回答
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
于 2013-07-01T11:45:44.597 回答