根据案例条件应用联接的 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 join
s。您的查询很难理解——它有问题中未描述的其他表和引用。
但想法是:
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(根据主键查询新增数据更新操作删除操作根据条件查询)