根据案例条件应用联接的 SQL 查询

Posted

技术标签:

【中文标题】根据案例条件应用联接的 SQL 查询【英文标题】:SQL Query to apply join on basis of case Condition 【发布时间】:2020-09-14 09:03:31 【问题描述】:

我有一个需求,我需要根据以下偏好获取区域表的维度键。

    根据物理地址(PA)的邮政编码获取维度键

    如果不满足第一个条件,则根据邮寄地址的邮政编码获取维度键

    如果第二个条件也不满足,则根据物理地址的教区代码获取维度键

    否则根据邮寄地址的教区代码获取维度键。

我正在尝试使用以下查询,但由于所有左连接都被评估,因此提供了多条记录。如果满足第一个条件,我希望它不应该继续第二个条件。

    select REGION_DIM_SK, CASE_NUM
    from (
        select distinct COALESCE(RDIM.REGION_DIM_SK, RDIM1.REGION_DIM_SK, RDIM2.REGION_DIM_SK, RDIM3.REGION_DIM_SK) AS REGION_DIM_SK
            , DC.CASE_NUM, ADDR_TYPE_CD
        FROM rpt_dm_ee_intg.CASE_PERSON_ADDRESS  dc
        left join  rpt_dm_ee_prsnt.REGION_DIM RDIM on dc.ZIP_CODE = RDIM.ZIP_CODE and RDIM.REGION_EFF_END_DT IS NULL and  dc.addr_type_cd='PA' AND dc.EFF_END_DT IS NULL 
        left join rpt_dm_ee_prsnt.REGION_DIM RDIM1 ON dc.ZIP_CODE = RDIM1.ZIP_CODE AND RDIM1.REGION_EFF_END_DT IS NULL AND dc.addr_type_cd='MA' AND DC.EFF_END_DT IS NULL 
        left join (
            select PARISH_CD, min(REGION_DIM_SK) as REGION_DIM_SK
            from  rpt_dm_ee_prsnt.REGION_DIM
            where REGION_EFF_END_DT is null
            group by PARISH_CD
        ) RDIM2 ON dc.addr_type_cd='PA' and dc.PARISH_CD = RDIM2.PARISH_CD AND DC.EFF_END_DT IS NULL
        left join (
            select PARISH_CD, min(REGION_DIM_SK) as REGION_DIM_SK
            from rpt_dm_ee_prsnt.REGION_DIM
            where REGION_EFF_END_DT is null
            group by PARISH_CD
        ) RDIM3 ON dc.addr_type_cd='MA' and dc.PARISH_CD = RDIM3.PARISH_CD AND DC.EFF_END_DT IS NULL
    ) A
    where REGION_DIM_SK is not null
) RD on RD.case_num = rpt_dm_ee_intg.CASE_PERSON_ELIGIBILITY.CASE_NUM

【问题讨论】:

您的查询不完整...(我猜)开始时缺少选择。 【参考方案1】:

使用多个left joins。您的查询很难理解——它有问题中未描述的其他表和引用。

但想法是:

select t.*,
       coalesce(rpa.dim_key, rm.dim_key, rpap.dim_key, rmp.dim_key) as dim_key
from t left join
     dim_region rpa
     on t.physical_address_zipcode = rpa.zipcode left join
     dim_region rm
     on t.mailing_address_zipcode = rm.zipcode and
        rpa.zipcode is null left join
     dim_region rpap
     on t.physical_addresss_parishcode = rpap.parishcode and
        rm.zipcode is null left join
     dim_region rmp
     on t.physical_addresss_parishcode = rmp.parishcode and
        rpap.zipcode is null
 

【讨论】:

【参考方案2】:

诀窍是把条件放在CASE WHEN:

SELECT  * 
FROM table1 a
JOIN table2 b
    ON CASE 
       WHEN a.code is not null and a.code = b.code THEN 1
       WHEN a.type = b.type THEN 1
       ELSE 0
   END = 1

对于您的示例,您可以将代码减少到两个联接,因为您要联接两个不同的表,所以不能在一个中完成。

SELECT CASE WHEN RDIM.addres IS NULL THEN RDIM2.addres ELSE RDIM.addres
FROM rpt_dm_ee_intg.CASE_PERSON_ADDRESS dc
LEFT JOIN rpt_dm_ee_prsnt.REGION_DIM RDIM ON CASE
        WHEN (dc.ZIP_CODE = RDIM.ZIP_CODE
           AND RDIM.REGION_EFF_END_DT IS NULL
           AND dc.addr_type_cd='PA'
           AND dc.EFF_END_DT IS NULL) THEN 1
        WHEN (dc.ZIP_CODE = RDIM1.ZIP_CODE
           AND RDIM1.REGION_EFF_END_DT IS NULL
           AND dc.addr_type_cd='MA'
           AND DC.EFF_END_DT IS NULL) THEN 1
        ELSE 0
    END = 1
LEFT JOIN
  (SELECT PARISH_CD,
          min(REGION_DIM_SK) AS REGION_DIM_SK
   FROM rpt_dm_ee_prsnt.REGION_DIM
   WHERE REGION_EFF_END_DT IS NULL
   GROUP BY PARISH_CD) RDIM2 ON CASE
        WHEN (dc.addr_type_cd='PA'
              AND dc.PARISH_CD = RDIM2.PARISH_CD
              AND DC.EFF_END_DT IS NULL
              AND RDIM.ZIP_CODE IS NULL) THEN 1
        WHEN (dc.addr_type_cd='MA'
              AND dc.PARISH_CD = RDIM3.PARISH_CD
              AND DC.EFF_END_DT IS NULL
              AND RDIM.ZIP_CODE IS NULL) THEN 1
        ELSE 0
    END = 1

编辑 如果您不想在RDIM1 邮政编码存在的情况下从RDIM2 表中获得空值,则可以轻松扩展逻辑以支持该逻辑。您只需将AND RDIM.ZIP_CODE IS NULL 添加到CASE WHEN 条件即可。

【讨论】:

如果任何案例在我的案例中只有物理地址或邮寄地址对于每一行都存在物理地址和邮寄地址,这将正常工作,因此这种情况显示两个地址的记录,理想情况下它应该只用于物理地址. 逻辑很容易扩展。如果您不想在 RDIM1 邮政编码存在的情况下从 RDIM2 表中获得空值,则可以轻松扩展逻辑以支持它。您只需将 AND RDIM.ZIP_CODE IS NULL 添加到 CASE WHEN 条件。

以上是关于根据案例条件应用联接的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

根据条件进行模糊查询

SQL Server:具有多个可能条件的案例语句中的模式匹配

Mybatis-Plus:ActiveRecord(根据主键查询新增数据更新操作删除操作根据条件查询)

SQL Server 条件联接

“where”条件在 JPA 中的联接查询中无法正常工作(本机查询)

如何编写没有联接的 JPA 2.1 更新条件查询?