Вернуть максимальную дату из нескольких таблиц - PullRequest
0 голосов
/ 03 сентября 2011

У меня есть 4 таблицы со следующей соответствующей информацией, которую я хочу получить.

Таблица: Staff_profile (STAFF_ID, STAFF_USERNAME, STAFF_NAME, STAFF_JOB_ID, STAFF_FACULTY_ID, STAFF_OFF_TEL, STAFF_EMAIL) - содержит информацию о персонале

Таблица: RFMUSERHISTORY (uh_staff_id, UH_DATETIME) - содержит историю входа

Таблица: RFMUSERROLEJOBMAP (role_id, job_id) - сопоставляет роль-2-job [это потому, что таблица заданий уже существует, и это новое приложение выбирает только определенные идентификаторы заданий для использования против своих таблица собственных ролей

Таблица: RFMUSERROLE (USERROLE_CODE, USERROLE_ID) - содержит информацию о ролях пользователей

Теперь я хочу получить информацию о последнем входе в систему (максимальную дату для этого пользователя в истории пользователей), включая сведения о роли и персонале для каждого конкретного человека, который входит в систему. У меня возникли проблемы с моим кодом, и в итоге я просто выбрал все записи для этого пользователя с UH_datetime заказал desc, чтобы я мог выбрать эту самую последнюю запись.

Пожалуйста, любая помощь приветствуется. Вот мой текущий код (очень неэффективный, как описано выше):

SELECT a.STAFF_ID, a.STAFF_USERNAME, a.STAFF_NAME, a.STAFF_JOB_ID, a.STAFF_FACULTY_ID, 
    a.STAFF_OFF_TEL, a.STAFF_EMAIL, to_CHAR(b.UH_DATETIME,'Dy DD-MM-YYYY HH24:MI:SS') 
    AS UH_DATETIME, e.USERROLE_CODE, e.USERROLE_ID  
        FROM STAFF_PROFILE a  
        LEFT JOIN RFMUSERHISTORY b ON STAFF_ID=b.uh_staff_id 
        LEFT JOIN RFMUSERROLEJOBMAP d ON a.STAFF_JOB_ID=d.job_id  
        LEFT JOIN RFMUSERROLE e ON d.role_id=e.userrole_id 
        WHERE STAFF_ID=:eid1 ORDER BY b.UH_DATETIME DESC

Спасибо

LUHFLUH

Ответы [ 2 ]

3 голосов
/ 03 сентября 2011

Вы можете использовать аналитическую функцию для ранжирования строк, а затем выбрать самую последнюю. Если вы действительно просто выбираете данные для одного STAFF_ID, это, вероятно, не более эффективно, чем вложение исходного запроса во внешний запрос, который выбирает строку с использованием предиката ROWNUM. Однако если вы выбираете данные для нескольких сотрудников, это должно быть более эффективным.

SELECT *
  FROM (
    SELECT a.STAFF_ID, 
           a.STAFF_USERNAME, 
           a.STAFF_NAME, 
           a.STAFF_JOB_ID, 
           a.STAFF_FACULTY_ID, 
           a.STAFF_OFF_TEL, 
           a.STAFF_EMAIL, 
           to_CHAR(b.UH_DATETIME,'Dy DD-MM-YYYY HH24:MI:SS') AS UH_DATETIME, 
           e.USERROLE_CODE, 
           e.USERROLE_ID,
           dense_rank() over (partition by a.staff_id order by b.uh_datetime desc) rnk
      FROM STAFF_PROFILE a  
            LEFT JOIN RFMUSERHISTORY b ON STAFF_ID=b.uh_staff_id 
            LEFT JOIN RFMUSERROLEJOBMAP d ON a.STAFF_JOB_ID=d.job_id  
            LEFT JOIN RFMUSERROLE e ON d.role_id=e.userrole_id 
      WHERE STAFF_ID=:eid1 
    )
 WHERE rnk = 1
1 голос
/ 03 сентября 2011

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

Другой вариант - ограничить Oracle одной строкой с rownum:

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