У меня возникла проблема с отсутствием данных 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" нет строки. Однако я не понимаю, почему внешнее объединение не возвращает nulls в этом случае, как это происходит в Oracle 11g, Mysql и т.д.
Я изучал и обнаружил документацию, в которой Oracle 12c имел ряд улучшений для внешних соединений, но ничего, что указывало на изменение, которое повлияло бы на это.
Кто-нибудь знает, почему это происходит только для Oracle 12c, и как лучше всего переписать это для работы в 12c и поддерживать совместимость с 11g, mysql и т.д.
EDIT: прилагаемые планы.
Oracle 11g:
Oracle 12c: