3

テーブル A には存在するがテーブル B には存在しないレコードを検索しようとしています。チェックする列が 1 つしかない場合は、

select col_A,col_B,......from A where col_A not in (select Col_A from B).

しかし、チェックする必要がある4つの列があります。

私はこのようなことをしましたが、これは機能しますが、完璧な方法ではありません

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

オラクルのドキュメントから

http://docs.oracle.com/cd/E11882_01/server.112/e26088/queries004.htm#SQLRF52341

「MINUS の例 次のステートメントは結果を MINUS 演算子と結合します。MINUS 演算子は、最初のクエリで返された一意の行のみを返しますが、2 番目のクエリでは返されません。」

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 に答える