Последняя сертификация для каждого отдельного сотрудника - PullRequest
0 голосов
/ 17 января 2020

Я присоединился к нескольким таблицам, чтобы получить данные, относящиеся к сертификации сотрудниками. У меня есть запрос, который дает мне идентификатор сотрудника, имя, дату начала сертификации JPM_DATE_6, дату окончания сертификации JPM_DATE_3 и список всех сертификатов (JPM_DESCR90), объединенных и разделенных символом ',' в столбце.

SELECT DISTINCT A.EMPLID, A.JOBCODE, A.JOBCODE_DESCR, A.EMPL_STATUS, 
A.LOCATION, A.LOCATION_DESCR, A.NAME, E.EMAILID, B.EMPLID, E.OPRID,LISTAGG(C.JPM_DESCR90,',') WITHIN GROUP ( ORDER BY 
C.JPM_DESCR90) AS CertConcat
FROM PS_NPS_VIEW_ALL A, (PS_PERSON_NAME B LEFT OUTER JOIN  PS_NPS_LIC_VW_RPT 
C ON  B.EMPLID = C.EMPLID ), PSOPRDEFN E
WHERE ( A.EFFDT =
    (SELECT MAX(A_ED.EFFDT) FROM PS_NPS_VIEW_ALL A_ED
    WHERE A.EMPLID = A_ED.EMPLID
      AND A.EMPL_RCD = A_ED.EMPL_RCD
      AND A_ED.EFFDT <= SYSDATE)
AND A.EFFSEQ =
    (SELECT MAX(A_ES.EFFSEQ) FROM PS_NPS_VIEW_ALL A_ES
    WHERE A.EMPLID = A_ES.EMPLID
      AND A.EMPL_RCD = A_ES.EMPL_RCD
      AND A.EFFDT = A_ES.EFFDT)
 AND A.EMPLID = B.EMPLID
 AND A.EMPLID = E.EMPLID
 AND A.PER_ORG = 'EMP'
 AND A.EMPL_STATUS='A'
 AND A.PAYGROUP NOT IN ('SUM','CWR'))
GROUP BY A.EMPLID, A.JOBCODE,A.JOBCODE_DESCR, A.EMPL_STATUS, A.LOCATION, 
A.LOCATION_DESCR, A.NAME, E.EMAILID, B.EMPLID, E.OPRID;

Это дало мне 8257 строк. Затем я попытался получить данные для каждого уникального идентификатора сотрудника, в результате чего я получил бы только одну сертификацию, т.е. самую высокую / последнюю сертификацию, которая имела самую высокую дату окончания сертификации JPM_DATE_3 и название сертификации (JPM_DESCR90)

SELECT DISTINCT A.EMPLID,A.JOBCODE, A.JOBCODE_DESCR, A.EMPL_STATUS, 
A.LOCATION, A.LOCATION_DESCR, A.NAME, E.EMAILID, B.EMPLID, E.OPRID, 
JPM_DATE_3 ,JPM_DATE_6,JPM_DESCR90
FROM PS_NPS_VIEW_ALL A, (PS_PERSON_NAME B LEFT OUTER JOIN  PS_NPS_LIC_VW_RPT 
C ON  B.EMPLID = C.EMPLID ), PSOPRDEFN E
WHERE ( A.EFFDT =
    (SELECT MAX(A_ED.EFFDT) FROM PS_NPS_VIEW_ALL A_ED
    WHERE A.EMPLID = A_ED.EMPLID
      AND A.EMPL_RCD = A_ED.EMPL_RCD
      AND A_ED.EFFDT <= SYSDATE)
AND A.EFFSEQ =
    (SELECT MAX(A_ES.EFFSEQ) FROM PS_NPS_VIEW_ALL A_ES
    WHERE A.EMPLID = A_ES.EMPLID
      AND A.EMPL_RCD = A_ES.EMPL_RCD
      AND A.EFFDT = A_ES.EFFDT)
 AND A.EMPLID = B.EMPLID
 AND A.EMPLID = E.EMPLID
 AND A.PER_ORG = 'EMP'
 AND A.EMPL_STATUS='A'
 AND A.PAYGROUP NOT IN ('SUM','CWR'))
 AND C.JPM_DATE_3=(SELECT MAX(JPM_DATE_3) FROM PS_NPS_LIC_VW_RPT V WHERE 
V.EMPLID=A.EMPLID and V.EMPLID=B.EMPLID AND V.EMPLID=C.EMPLID AND 
V.EMPLID=E.EMPLID )
 GROUP BY A.EMPLID,A.JOBCODE, A.JOBCODE_DESCR, A.EMPL_STATUS, A.LOCATION, 
A.LOCATION_DESCR, A.NAME, E.EMAILID, B.EMPLID, E.OPRID, JPM_DATE_3 
,JPM_DATE_6,JPM_DESCR90;

Однако это дало мне 5807 уникальных рядов. В ходе дальнейших исследований я обнаружил, что было довольно много значений JPM_DATE_3 и JPM_DATE_6, которые были нулевыми, и поэтому я не получал желаемый счетчик. Пожалуйста, предложите изменить запрос, который даст мне уникальные идентификаторы сотрудников. последние сертификаты JPM_DESCR90 для самой высокой даты JPM_DATE_3, а также даст мне строки, где JPM_DATE_3 имеет значение null, чтобы я мог иметь 8257 уникальных строк, которые должны были быть для каждого идентификатора сотрудника.

1 Ответ

0 голосов
/ 17 января 2020

Это запрос top-n, вы ищете последние строки здесь и там. Самый простой способ - использовать row_number(), вы должны быть осторожны только с предложениями partition by и order by. Затем возьмите первую строку для каждого сотрудника, сертификат.

Вот запрос, объединяющий две задачи, в нем перечислены все сертификаты, а также показаны сведения о последних:

select emplid, name, oprid, jpm_date_3 as last_cert_date3, jpm_date_6 as last_cert_date6,
       jpm_descr90 as last_cert_descr, all_certificates
  from (
    select a.emplid, a.name, e.oprid, c.jpm_date_3, c.jpm_date_6, c.jpm_descr90,
           listagg(c.jpm_descr90,',') within group (order by c.jpm_descr90) 
             over (partition by a.emplid) as all_certificates,
           row_number() over (partition by a.emplid order by jpm_date_3 desc) rnc
      from (
        select ps_nps_view_all.*, 
               row_number() over (partition by emplid, empl_rcd 
                                  order by effdt desc, effseq desc) rna
          from ps_nps_view_all
          where per_org = 'EMP' and empl_status = 'A' 
            and paygroup not in ('SUM', 'CWR') and effdt <= sysdate ) a
      join ps_person_name         b on b.emplid = a.emplid
      left join ps_nps_lic_vw_rpt c on c.emplid = a.emplid
      join psoprdefn              e on e.emplid = a.emplid
      where rna = 1 )
  where rnc = 1

dbfiddle demo (у Джона нет сертификатов, у Тома две, а также две строки в главной таблице, мы берем последнюю.)

Обратите внимание, что аналитические функции (row_number, listagg с предложением over) позволяет касаться данных только один раз, не нужно самостоятельно объединяться и искать максимальные значения в подзапросах. Также, пожалуйста, используйте соединения в стандарте ANSI, это делает вещи более читабельными.

Проблема в вашем запросе заключается в том, что вы оставили присоединенные сертификаты, но затем в предложении where вы пытались найти последний (... AND C.JPM_DATE_3= ...) который изменил левое соединение на внутреннее соединение и часть строк была потеряна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...