SQL-запрос для применения объединения на основе условия обращения

#sql #sql-server #sql-server-2014

#sql #sql-сервер #sql-server-2014

Вопрос:

У меня есть требование, при котором мне нужно получить ключ измерения таблицы регионов на основе следующего предпочтения.

  1. Получение ключа измерения на основе почтового индекса физического адреса (PA)

  2. Если первое условие не выполняется, извлеките ключ измерения на основе почтового индекса почтового адреса

  3. Если второе условие также не выполняется, извлеките ключ измерения на основе кода прихода физического адреса

  4. Еще извлеките ключ измерения на основе кода прихода почтового адреса.

Я пытаюсь использовать приведенный ниже запрос, но выдает несколько записей, поскольку оцениваются все левые соединения. Я хочу, чтобы оно не выполнялось по второму условию, если выполнено первое условие.

     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 РАВЕН НУЛЮ для СЛУЧАЯ, КОГДА условия.