Oracle SQL: получение записей по самой последней дате - PullRequest
0 голосов
/ 08 июня 2018

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

Базовый сценарий:

SELECT DISTINCT EMPLOYEE "E.EMPLOYEE #",
LR.DESCRIPTION "Role", 
R.ROLE_STATUS "Status",
R.ROLE_START_DATE "Role Start"
FROM EMPLOYEES E
JOIN ROLES R ON E.EMPLOYEE_ID = R.EMPLOYEE_ID
JOIN LU_ROLES LR ON R.ROLE_ID = LR.ROLE_ID
WHERE ROLE_START_DATE <= DATE '2017-12-03'
ORDER BY 1

Результаты:

Employee #  |   Role  |  Status  |  Role Start
23432        Associate  Not Active 04/23/2011    
23432        Manager    Active     11/2/2012
54334        Analyst    Resigned   10/15/2015
12311        Help Desk  Not Active 05/12/2014
12311        Analyst    Not Active 06/11/2015
12311        Supervisor Active     07/12/2016

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

SELECT DISTINCT EMPLOYEE "E.EMPLOYEE #",
LR.DESCRIPTION, 
R.ROLE_STATUS,
MAX(ROLE_START_DATE)
FROM EMPLOYEES E
JOIN ROLES R ON E.EMPLOYEE_ID = R.EMPLOYEE_ID
JOIN LU_ROLES LR ON R.ROLE_ID = LR.ROLE_ID
WHERE ROLE_START_DATE >= DATE '2017-12-03'
GROUP BY E.EMPLOYEE, LR.DESCRIPTION, R.ROLE_STATUS
ORDER BY 1

Что бы я хотел получить:

Employee #  |   Role  |  Status  |  Role Start
23432        Manager    Active     11/2/2012
54334        Analyst    Resigned   10/15/2015
12311        Supervisor Active     07/12/2016

Буду очень признателен за любую помощь или совет.

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 08 июня 2018

Лучший способ сделать это с помощью оконных функций (что Oracle называет аналитическими функциями).Если вы хотите вернуть связи (сотрудники с несколькими ролями с одинаковой датой начала), тогда используйте RANK() или DENSE_RANK();если вам нужна произвольная роль с самой поздней датой начала, используйте ROW_NUMBER():

SELECT employee AS "E.EMPLOYEE #"
     , description AS "Role"
     , role_status AS "Status"
     , role_start_date "Role Start"
  FROM (
    SELECT e.employee, lr.description, r.role_status, r.role_start_date
         , RANK() OVER ( PARITION BY e.employee ORDER BY r.role_start_date DESC ) AS rn
      FROM employees e INNER JOIN roles r
        ON e.employee_id = r.employee_id
     INNER JOIN lu_roles lr
        ON lr.role_id = r.role_id
     WHERE r.role_start_dt >= DATE'2017-12-03'
) WHERE rn = 1;

Надеюсь, это поможет.

0 голосов
/ 08 июня 2018

Вы можете использовать ROW_NUMBER/RANK в сочетании с FETCH FIRST ... WITH TIES (Oracle 12c):

SELECT e.employee, lr.description, r.role_status, r.role_start_date
FROM employees e 
JOIN roles r
  ON e.employee_id = r.employee_id
JOIN lu_roles lr
  ON lr.role_id = r.role_id
 WHERE r.role_start_dt >= DATE'2017-12-03'
ORDER BY RANK() OVER (PARITION BY e.employee ORDER BY r.role_start_date DESC)
FETCH FIRST 1 ROW WITH TIES;
0 голосов
/ 08 июня 2018

Посмотрите, поможет ли это -

SELECT * FROM (
SELECT DISTINCT EMPLOYEE "E.EMPLOYEE #",
LR.DESCRIPTION "Role", 
R.ROLE_STATUS "Status",
R.ROLE_START_DATE "Role Start",
DENSE_RANK() OVER (PARTITION BY EMPLOYEE ORDER BY ROLE_START_DATE DESC) AS RNK
FROM EMPLOYEES E
JOIN ROLES R ON E.EMPLOYEE_ID = R.EMPLOYEE_ID
JOIN LU_ROLES LR ON R.ROLE_ID = LR.ROLE_ID
WHERE ROLE_START_DATE >= DATE '2017-12-03'
ORDER BY 1
) WHERE RNK = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...