Подход объединения отлично работает для небольших и средних таблиц, но имеет низкую производительность для больших таблиц. Проблема в том, что вы должны объединить все лекарства со всеми побочными эффектами только для того, чтобы отказаться от всех, кроме ближайшей комбинации.
Альтернативный подход, который должен масштабироваться, использует унифицированное представление для обеих таблиц с аналитической функцией поиска в записи LAG
ing, чтобы получить местоположение.
По этому запросу создается унифицированное представление. Обратите внимание, что для выделения источника строки добавлен новый столбец SOURCE_TYPE
.
with tab as (
select SID, SNAME, START_DATE, 'SIDE_EFFECT' source_type,cast (null as varchar2(25)) MEDICALLOCATION, SideEffect from SideEffect
union all
select MID, MNAME, START_DATE, 'MEDICATION' source_type, MEDICALLOCATION, null as SideEffect from Medication
)
select SID, SNAME, START_DATE, SOURCE_TYPE, MEDICALLOCATION, SIDEEFFECT
from tab
where SID = 'I1F-BE' and SNAME = '132~1202'
order by 1,2,3;
SID SNAME START_DATE SOURCE_TYPE MEDICALLOCATION SIDEEFFECT
---------- ---------- ------------------- ----------- ------------------------- -------------------------
I1F-BE 132~1202 23.07.2015 00:00:00 MEDICATION ABDOMEN
I1F-BE 132~1202 24.07.2015 00:00:00 SIDE_EFFECT Injection Site Reaction
Единственная дополнительная логика, необходимая для записи SIDE_EFFECT
, если перед ней непосредственно стоит запись MEDICATION
, чтобы получить значение столбца MEDICALLOCATION
из запаздывающей записи.
Аналитическая функция LAG
использует PARTITION BY
в столбцах ключей объединения, а ORDER BY
определяется start_date
.
После перемещения местоположения в строку site_effect вы можете отказаться от всех записей лекарств.
Окончательный запрос
with tab as (
select SID, SNAME, START_DATE, 'SIDE_EFFECT' source_type,cast (null as varchar2(25)) MEDICALLOCATION, SideEffect from SideEffect
union all
select MID, MNAME, START_DATE, 'MEDICATION' source_type, MEDICALLOCATION, null as SideEffect from Medication
),
tab2 as (
select SID, SNAME, START_DATE, SOURCE_TYPE, MEDICALLOCATION, SIDEEFFECT,
CASE when SOURCE_TYPE = 'SIDE_EFFECT' and
lag(SOURCE_TYPE) over (partition by SID, SNAME order by START_DATE) = 'MEDICATION' then
lag(MEDICALLOCATION) over (partition by SID, SNAME order by START_DATE)
END as SIDEEFFECT_MEDICALLOCATION
from tab)
select SID, SNAME, START_DATE, SIDEEFFECT, SIDEEFFECT_MEDICALLOCATION
from tab2
where source_type = 'SIDE_EFFECT'
order by 1,2,3;
SID SNAME START_DATE SIDEEFFECT SIDEEFFECT_MEDICALLOCATION
---------- ---------- ------------------- ------------------------- --------------------------
I1F-BE 132~1201 23.06.2015 00:00:00 UTI
I1F-BE 132~1201 25.07.2018 00:00:00 Basal Cell carcinoma THIGH
I1F-BE 132~1202 24.07.2015 00:00:00 Injection Site Reaction ABDOMEN
I1F-BE 132~1203 05.08.2015 00:00:00 Injection Site Reaction ABDOMEN
I1F-BE 132~1204 10.08.2015 00:00:00 Viral Syndrome
...