オラクルのドキュメントから
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
);