我有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作业[这是因为作业表预先存在而且这个新应用程序只选择要使用的某些作业ID它自己的角色表
表: RFMUSERROLE(USERROLE_CODE,USERROLE_ID) - 保存用户角色信息
现在我想获取最后一次登录(userhistory中该用户的最大日期)详细信息,包括登录的任何特定人员的角色和员工详细信息。我的代码出现问题,最后只是选择了所有记录对于具有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
答案 0 :(得分:3)
您可以使用分析函数对行进行排名,然后选择最新的行。如果您真的只是选择单个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 :(得分:1)
在您要求之前,Oracle不会通过网络发送行。如果您的客户端代码只请求第一行,那么您的查询应该足够有效。
另一种选择是使用rownum
将Oracle限制为一行:
where rownum = 1