Фильтрация записей из набора данных postgres(greenplum) по значению поля

Существует запрос возвращающий набор справочных данных. Для добавления описания поля depo_rem мы соединяем набор данных с справочником ref_stanh__som_df1d__t. В некоторых случаях, в справочнике есть строки дубликаты, из которых надо выбрать только ту строку(описание поля depoh2.snames AS depo_rem_name), где поле gr = 31.

Для демонстрации проблемы, написал запрос с таким случаем:

SELECT 
    rcom_14b_t.extract_dttm,
    rcom_14b_t.extract_guid,
    rcom_14b_t.sec_mod,
    sertps.fname AS sec_mod_name,
    rcom_14b_t.sec_num,
    rcom_14b_t.sec_code,
    rcom_14b_t.depo_sec,
    depoh1.snames AS depo_sec_name,
    rcom_14b_t.id,
    rcom_14b_t.iskl,
    rcom_14b_t.pr_nep_ep,
    rcom_14b_t.depo_rem,
    depoh2.snames AS depo_rem_name,
    depoh2.gr,  
    rcom_14b_t.strr,
    rcom_14b_t.dt_0,
    rcom_14b_t.dt_1,
    rcom_14b_t.station_1,
    stanh1.fname AS station_1_name,
    rcom_14b_t.fuel_1,
    rcom_14b_t.dt_2,
    rcom_14b_t.station_2,
    stanh2.fname AS station_2_name,
    rcom_14b_t.fuel_2,
    rcom_14b_t.otchmonth,
    rcom_14b_t.otchyear,
    rcom_14b_t.otchdor,
    rr.sname AS otchdor_name
FROM hes.rcom_14b__som_df1d__t rcom_14b_t
LEFT JOIN hes.ref_dor__som_df1d__t rr ON rcom_14b_t.otchdor = rr.code
LEFT JOIN hes.ref_sertps__som_df1d__t sertps ON rcom_14b_t.sec_mod = sertps.code AND date(rcom_14b_t.dt_0) >= sertps.dtbegd AND date(rcom_14b_t.dt_1) <= sertps.dtendd
LEFT JOIN hes.ref_depoh__som_df1d__t depoh1 ON rcom_14b_t.depo_sec = depoh1.code AND date(rcom_14b_t.dt_0) >= depoh1.dtbegs AND date(rcom_14b_t.dt_0) <= depoh1.dtends
left join hes.ref_depoh__som_df1d__t as depoh2 on rcom_14b_t.depo_rem = depoh2.code AND ( rcom_14b_t.dt_0 >= depoh2.dtbegs AND rcom_14b_t.dt_0 <= depoh2.dtends )
LEFT JOIN hes.ref_stanh__som_df1d__t stanh1 ON rcom_14b_t.station_1 = stanh1.code6 AND date(rcom_14b_t.dt_0) >= stanh1.dtbegs AND date(rcom_14b_t.dt_0) <= stanh1.dtends
LEFT JOIN hes.ref_stanh__som_df1d__t stanh2 ON rcom_14b_t.station_2 = stanh2.code6 AND date(rcom_14b_t.dt_0) >= stanh2.dtbegs AND date(rcom_14b_t.dt_0) <= stanh2.dtends
where rcom_14b_t.sec_mod = 625 and depo_sec = 112 and fuel_2 = 1632;

Дублирование записей справочника

Имеющееся решение имеет проблемы производительности:

SELECT rcom_14b_t.extract_dttm,
    rcom_14b_t.extract_guid,
    rcom_14b_t.sec_mod,
    sertps.fname AS sec_mod_name,
    rcom_14b_t.sec_num,
    rcom_14b_t.sec_code,
    rcom_14b_t.depo_sec,
    depoh1.snames AS depo_sec_name,
    rcom_14b_t.id,
    rcom_14b_t.iskl,
    rcom_14b_t.pr_nep_ep,
    rcom_14b_t.depo_rem,
    depoh2.snames AS depo_rem_name,
    rcom_14b_t.strr,
    rcom_14b_t.dt_0,
    rcom_14b_t.dt_1,
    rcom_14b_t.station_1,
    stanh1.fname AS station_1_name,
    rcom_14b_t.fuel_1,
    rcom_14b_t.dt_2,
    rcom_14b_t.station_2,
    stanh2.fname AS station_2_name,
    rcom_14b_t.fuel_2,
    rcom_14b_t.otchmonth,
    rcom_14b_t.otchyear,
    rcom_14b_t.otchdor,
    rr.sname AS otchdor_name
   FROM hes.rcom_14b__som_df1d__t rcom_14b_t
     LEFT JOIN hes.ref_dor__som_df1d__t rr ON rcom_14b_t.otchdor = rr.code
     LEFT JOIN hes.ref_sertps__som_df1d__t sertps ON rcom_14b_t.sec_mod = sertps.code AND date(rcom_14b_t.dt_0) >= sertps.dtbegd AND date(rcom_14b_t.dt_1) <= sertps.dtendd
     LEFT JOIN hes.ref_depoh__som_df1d__t depoh1 ON rcom_14b_t.depo_sec = depoh1.code AND date(rcom_14b_t.dt_0) >= depoh1.dtbegs AND date(rcom_14b_t.dt_0) <= depoh1.dtends
     LEFT JOIN LATERAL ( SELECT depoh2_1.snames
           FROM hes.ref_depoh__som_df1d__t depoh2_1
          WHERE rcom_14b_t.depo_rem = depoh2_1.code AND rcom_14b_t.dt_0 >= depoh2_1.dtbegs AND rcom_14b_t.dt_0 <= depoh2_1.dtends
          ORDER BY
                CASE depoh2_1.gr
                    WHEN 31 THEN 1
                    ELSE 2
                END
         LIMIT 1) depoh2 ON 1 = 1
     LEFT JOIN hes.ref_stanh__som_df1d__t stanh1 ON rcom_14b_t.station_1 = stanh1.code6 AND date(rcom_14b_t.dt_0) >= stanh1.dtbegs AND date(rcom_14b_t.dt_0) <= stanh1.dtends
     LEFT JOIN hes.ref_stanh__som_df1d__t stanh2 ON rcom_14b_t.station_2 = stanh2.code6 AND date(rcom_14b_t.dt_0) >= stanh2.dtbegs AND date(rcom_14b_t.dt_0) <= stanh2.dtends;

Как решить эту задачу оптимальнее?

Использую: PostgreSQL 9.4.26 (Greenplum Database 6.21.3 build commit:622fa9a831d189db93b0e2c348f1379d7d5f6e9d Open Source) on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 6.4.0, 64-bit compiled on Oct 27 2022 17:36:45


Ответы (0 шт):