【问题标题】:Join with same table with three different conditions在三个不同条件下加入同一张表
【发布时间】:2021-07-19 04:44:51
【问题描述】:

我需要在三个不同条件下加入同一张表。以下是场景:

表 1:

ID,NAME,INSERT_DT

表2:

ID_FK,DESC,REC_BEG_DT,REC_END_DT,REC_INDC,SYSTEM_CODE,SERVICE_SRT_DT,SERVICE_END_DT

加盟条件:

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

如果没有返回结果,则使用连接条件 2。
如果上述条件返回多个结果,则选择满足的一个

Table1.INSERT_DT >= Table2.REC_BEG_DT AND Table1.INSERT_DT <= Table2.REC_END_DT
  1. Table1.ID=Table2.ID_FK SYSTEM_CODE='ABC' REC_INDC='A'

    如果没有返回结果,则使用连接条件 3。
    如果上述条件返回多个结果,则选择满足的一个

    Table1.INSERT_DT >= Table2.REC_BEG_DT AND Table1.INSERT_DT

  2. Table1.ID=Table2.ID_FK SYSTEM_CODE='ABC'

    如果没有结果返回 Null。
    如果上述条件返回多个结果,则选择满足的一个

    Table1.INSERT_DT >= Table2.REC_BEG_DT AND Table1.INSERT_DT

添加样本输入和输出

表1

表2

编辑: 增加了一个场景

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

逻辑上应该选择表中的第一条记录。

谢谢

【问题讨论】:

  • 请以文本格式提供示例数据和所需的输出。
  • “如果上述条件返回多个结果,则选择满足..的那个。”因此查询必须返回不超过一行。 ?
  • 是的@Serg,它将返回不超过一行
  • @KaziMohammadAliNur 我已添加
  • 要复制情况示例输入需要采用文本格式而不是图像。请上传文本数据。

标签: sql oracle


【解决方案1】:

您可以使用可选条件优先级标志标记行并选择具有最高优先级的行。查询模板

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

编辑

考虑所有 REC_INDC ='I' 情况

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

横向在这里只是为了方便,表达式可以很容易地合并到 SELECT 列表中。

db<>fiddle

【讨论】:

  • 非常感谢@Serg。能否请您多解释一下优先级标志,这将非常有帮助。
  • 例如,带有 '009' 标志 (REC_INDC='A' ) 和 (Table1.INSERT_DT >= Table2.SERVICE_SRT_DT AND Table1.INSERT_DT
  • 非常感谢@Serg,它对我有很大帮助
  • 当所有 REC_INDC ='I' 并且任何数据都有 Table1.INSERT_DT >= Table2.SERVICE_SRT_DT AND Table1.INSERT_DT 的顺序拉取不正确的数据
  • 请将示例数据显示为文本和案例所需的结果。
猜你喜欢
  • 1970-01-01
  • 2012-08-22
  • 2014-09-15
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-27
  • 1970-01-01
相关资源
最近更新 更多