Oracle 12c で欠落しているデータに関する問題が発生しました。
コードを調べたところ、mysql、mssql、oracle 11g では動作するが、oracle 12c では動作が異なるクエリが見つかりました。
テーブル構造とクエリをある程度一般化し、問題を再現しました。
create table thing (thing_id number, display_name varchar2(500));
create table thing_related (related_id number, thing_id number, thing_type varchar2(500));
create table type_a_status (related_id number, status varchar2(500));
create table type_b_status (related_id number, status varchar2(500));
insert into thing values (1, 'first');
insert into thing values (2, 'second');
insert into thing values (3, 'third');
insert into thing values (4, 'fourth');
insert into thing values (5, 'fifth');
insert into thing_related values (101, 1, 'TypeA');
insert into thing_related values (102, 2, 'TypeB');
insert into thing_related values (103, 3, 'TypeB');
insert into thing_related (related_id, thing_id) values (104, 4);
insert into type_a_status values (101, 'OK');
insert into type_b_status values (102, 'OK');
insert into type_b_status values (103, 'NOT OK');
クエリの実行:
SELECT t.thing_id AS id, t.display_name as name,
tas.status as type_a_status,
tbs.status as type_b_status
FROM thing t LEFT JOIN thing_related tr
ON t.thing_id = tr.thing_id
LEFT JOIN type_a_status tas
ON (tr.related_id IS NOT NULL
AND tr.thing_type = 'TypeA'
AND tr.related_id = tas.related_id)
LEFT JOIN type_b_status tbs
ON (tr.related_id IS NOT NULL
AND tr.thing_type = 'TypeB'
AND tr.related_id = tbs.related_id)
Oracle 11g では次のようになります (これはSQL Fiddleです):
ID | NAME | TYPE_A_STATUS | TYPE_B_STATUS
1 | first | OK | (null)
2 | second | (null) | OK
3 | third | (null) | NOT OK
4 | fourth | (null) | (null)
5 | fifth | (null) | (null)
Oracle 12c での同じスキーマ、データ、およびクエリ:
ID | NAME | TYPE_A_STATUS | TYPE_B_STATUS
1 | first | OK | (null)
2 | second | (null) | OK
3 | third | (null) | NOT OK
4 | fourth | (null) | (null)
'thing_related' に結合する行がないため、2 番目の 2 つの外部結合では何も返されていないようです。ただし、この場合、Oracle 11g、Mysqlなどのように、外部結合がnullを返さない理由がわかりません.
私は調査を行っており、Oracle 12c には外部結合の多くの機能強化があったドキュメントを見つけましたが、これに影響を与える変更を強調するものはありませんでした。
これがOracle 12cでのみ発生する理由を知っている人はいますか?12cで動作し、11g、mysqlなどとの互換性を維持するには、これをどのように書き直すのが最善でしょうか?
編集:添付の計画。
オラクル 11g:
オラクル 12c: