#sql #sql-server #sql-server-2014
#sql #sql-сервер #sql-server-2014
Вопрос:
У меня есть требование, при котором мне нужно получить ключ измерения таблицы регионов на основе следующего предпочтения.
-
Получение ключа измерения на основе почтового индекса физического адреса (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. Ваш запрос не завершен … (я предполагаю), что в начале отсутствует select.
Ответ №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
Редактировать
Если вы не хотите иметь нули из RDIM2
таблицы, если RDIM1
присутствует почтовый индекс, логику можно легко расширить для поддержки этого. Вам просто нужно добавить AND RDIM.ZIP_CODE IS NULL
к CASE WHEN
условиям.
Комментарии:
1. это будет работать нормально, если в любом случае есть только физический или почтовый адрес, в моем случае для каждой строки присутствуют как физический, так и почтовый адреса, поэтому это условие показывает запись для обоих адресов, в идеале это должно быть только для физического адреса.
2. Логику можно легко расширить. Если вы не хотите иметь нули из таблицы RDIM2, если присутствует почтовый индекс RDIM1, логику можно легко расширить для поддержки этого. Вам просто нужно добавить И RDIM. ZIP_CODE РАВЕН НУЛЮ для СЛУЧАЯ, КОГДА условия.