Не могу правильно заказать запрос - PullRequest
0 голосов
/ 19 февраля 2019

Некоторое время назад я попросил помочь кодировать фильтрацию LEFT JOIN определенным образом, чтобы результат поместил желаемое значение в первую строку.

Требуется получить последнюю вставленную / обновленную запись таблицы снекоторые исключения

Дело в том, что есть много случаев, которые смешивают данные.Сценарий состоит в том, что в одной таблице у нас есть 2 значения, которые нам нужно организовать в разных столбцах.PO_ID является уникальным, но может иметь 1 или более значений в других таблицах, и для этого конкретного случая 1 PO_ID имеет 3 значения SHIP_ID_CUS.Нам нужен только 1 PO_ID на строку (без дубликатов), поэтому мы использовали MAX () и GROUP BY.

Вот фрагмент кода, который, я думаю, вызывает проблемы.

select
z.po_id,
max(scdc.ship_id) as ship_id_cdc,
max(lscdc.ship_evnt_cd) as last_event_cdc,
max(lscdc.ship_evnt_tms) as event_tms_cdc,
max(scus.SHIP_ID) as ship_id_cus, 
max(lscus.ship_evnt_cd) as last_event_cus,
max(lscus.ship_evnt_tms) as event_tms_cus

from TABLE.A z
left join (select distinct po_id, iltc.ship_id, s.ship_to_loc_code from TABLE.B iltc inner join TABLE.C s on iltc.ship_id=s.ship_id and iltc.ship_to_loc_code=s.ship_to_loc_code and s.ship_to_ctry<>'   ') AS A ON z.po_id = a.po_id
left JOIN TABLE.C scus ON A.SHIP_ID = scus.SHIP_ID AND A.SHIP_TO_LOC_CODE = scus.SHIP_TO_LOC_CODE and scus.loc_type = 'CUS' AND DAYS(scus.shipment_tms)+10 >= DAYS(z.ship_tms)
left JOIN TABLE.C scdc ON A.SHIP_ID = scdc.SHIP_ID AND A.SHIP_TO_LOC_CODE = scdc.SHIP_TO_LOC_CODE and scdc.loc_type = 'CDC' AND DAYS(scdc.shipment_tms)+10 >= DAYS(z.ship_tms)

left join 

(    select ship_id_856, ship_to_loc_cd856, ship_evnt_cd, ship_evnt_tms, carr_tracking_num, event_srv_lvl
            ,        row_number() over(partition by ship_id order by updt_job_tms desc) as RN
            FROM     TABLE.D
         WHERE LEFT(ship_evnt_cd, 1) <> '9') lscus
ON        lscus.ship_id_856=scus.ship_id and scus.ship_to_loc_code=lscus.ship_to_loc_cd856 and lscus.rn = 1

left join 

(    select ship_id_856, ship_to_loc_cd856, ship_evnt_cd, ship_evnt_tms, carr_tracking_num, event_srv_lvl
           ,        row_number() over(partition by ship_id order by updt_job_tms desc) as RN
            FROM     TABLE.D
         WHERE LEFT(ship_evnt_cd, 1) <> '9') lscdc
ON        lscdc.ship_id_856=scdc.ship_id and lscdc.ship_to_loc_cd856=scdc.ship_to_loc_code and lscdc.rn = 1

WHERE
z.po_id = 'T1DLDC'
GROUP BY z.po_id  

При поиске этого условия мы получаем следующий результат

enter image description here

Проблема заключается в том, что если мы ищем непосредственно в TABLE.D, последнее событие, котороенам нужно (с последней записью обновления tms) еще одна (X1) и почему-то дата неверная.

enter image description here

Что еще более странно, так эточто если мы ищем ship_id_cus в исходном запросе, мы получим правильный код, но с неправильной датой ...

WHERE
--z.po_id = 'T1DLDC'
scus.ship_id = 'D30980'
GROUP BY z.po_id 

enter image description here

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

left JOIN ( select * from TABLE.C order by updt_job_tms desc) scus ON A.SHIP_ID = scus.SHIP_ID AND A.SHIP_TO_LOC_CODE = scus.SHIP_TO_LOC_CODE and scus.loc_type = 'CUS' AND DAYS(scus.shipment_tms)+10 >= DAYS(z.ship_tms)

Но это также дает те же точные результаты при поиске по po_id или ship_id_cus

Любые идеи иликомментарий будет высоко оценен.

Спасибо

------------------------------------UPDATE -----------------------------------

Добавление результата LEFT JOINс row_partition (), включая все ship_id_cus для этого po_id и все коды с tms.Здесь нет совпадений.

enter image description here

Исходя из всего этого, это должен быть последний ship_id_cus с событием X1 / tms.Если исключить также те, которые начинаются с 9, мы получим следующий результат.

enter image description here

(я не применяю здесь упорядочение по ship_id_cus, которое ужеописано ранее, что не работает ни так, как я реализовал)

1 Ответ

0 голосов
/ 19 февраля 2019

Если у вас есть таблица: TBL1

ID     APPROVED APPROVER DATE_APPROVED
====== ======== ======== =============
ABC    Y        JOE      2019-01-13
ABC    N        ZACK     2018-12-23
ABC    N        SUE      2019-02-23   

А вы делаете SQL:

SELECT ID, MAX(APPROVED) AS APPROVAL
,MAX(APPROVER) AS APPROVED_BY , MAX(DATE_APPROVED) AS APPROVED_ON
FROM TBL1 GROUP BY ID

вы получите результат:

ID     APPROVAL APPROVED_BY APPROVED_ON
====== ======== =========== =============
ABC    Y        ZACK        2019-02-23

, что правильно для кода, но НЕ то, что вы хотите

Попробуйте следующее:

SELECT T1.ID, T1.APPROVED, T1.APPROVER, T1.DATE_APPROVED
FROM TBL1 AS T1
INNER JOIN (SELECT ID, MAX(DATE_APPROVED) AS APPROVED_ON
FROM TBL1 GROUP BY ID
) AS T2
ON T1.ID =T2.ID
AND T1.DATE_APPROVED = T2.APPROVED_ON

Результат:

ID     APPROVED APPROVER DATE_APPROVED
====== ======== ======== =============
ABC    N        SUE      2019-02-23
...