I have a requirement to join with same table with three different conditions. Below are the scenarios:
Table1 :
ID,NAME,INSERT_DT
Table2 :
ID_FK,DESC,REC_BEG_DT,REC_END_DT,REC_INDC,SYSTEM_CODE,SERVICE_SRT_DT,SERVICE_END_DT
Joining Conditions:
1.
Table1.ID=Table2.ID_FK
SYSTEM_CODE='ABC'
REC_INDC='A'
Table1.INSERT_DT >= Table2.SERVICE_SRT_DT AND Table1.INSERT_DT <= Table2.SERVICE_END_DT
If no results return use join condition 2.
If the above condition return multiple results then pick the one that satisfy
Table1.INSERT_DT >= Table2.REC_BEG_DT AND Table1.INSERT_DT <= Table2.REC_END_DT
Table1.ID=Table2.ID_FK SYSTEM_CODE=’ABC’ REC_INDC=’A’
If no results return use join condition 3.
If the above condition return multiple results then pick the one that satisfyTable1.INSERT_DT >= Table2.REC_BEG_DT AND Table1.INSERT_DT <= Table2.REC_END_DT
Table1.ID=Table2.ID_FK SYSTEM_CODE=’ABC’
If no results return Null.
If the above condition return multiple results then pick the one that satisfyTable1.INSERT_DT >= Table2.REC_BEG_DT AND Table1.INSERT_DT <= Table2.REC_END_DT
Adding sample input and output
Table1
Table2
Edit: Added one more scenario
Tab1
|ID|NAME|INSERT_DT|
|1|XY|29/04/2021|
Tab2
ID_FK|DESC|REC_BEG_DT|REC_END_DT|REC_INDC|SYSTEM_CODE|SERVICE_SRT_DT|SERVICE_END
1|XY DESC1|1/4/2021|30/04/2021|I|ABC|1/3/2021|30/03/2021
1|XY DESC2|1/3/2021|30/03/2021|I|ABC|1/4/2021|30/04/2021
1|XY DESC2|1/3/2021|30/03/2021|I|ABC|1/3/2021|30/03/2021
Logically 1st record from table should be selected.
Thank you
Advertisement
Answer
You can flag rows with optional conditions priority flags and select a row with the highest priority. A query template
select
from
(
select ,
-- priority flags of optional conditions
row_number() over(partition by Table1_id order by
case when REC_INDC='A' then '0' else '9' end
|| case when Table1.INSERT_DT >= Table2.SERVICE_SRT_DT AND Table1.INSERT_DT <= Table2.SERVICE_END_DT then '0' else '9' end
|| case when Table1.INSERT_DT >= Table2.REC_BEG_DT AND Table1.INSERT_DT <= Table2.REC_END_DT then '0' else '9' end ) rn
from
where
-- mandatory condition
Table1.ID=Table2.ID_FK
AND SYSTEM_CODE='ABC'
) t
where rn = 1
EDIT
To take all REC_INDC =’I’ case into account
select *
from (
select table1.INSERT_DT, table2.* ,
f.flags,
row_number() over(partition by Table1.id order by f.flags) rn
from table1
join Table2 on
-- mandatory condition
Table1.ID=Table2.ID_FK
AND SYSTEM_CODE='ABC'
cross join lateral(
-- priority flags of optional conditions
select case when REC_INDC='A' and Table1.INSERT_DT >= Table2.SERVICE_SRT_DT AND Table1.INSERT_DT <= Table2.SERVICE_END_DT then '00'
else
case when REC_INDC='A' then '90' else '99' end end
|| case when Table1.INSERT_DT >= Table2.REC_BEG_DT AND Table1.INSERT_DT <= Table2.REC_END_DT then '0' else '9' end flags
from dual ) f
) t
where rn = 1
Lateral is here just as a convinience, the exprssion can be easyly merged into SELECT list.