我在Oracle数据库中有几个与员工记录相关的表。这些表中的每一个都包含三个相似的列:EMPLOYEE_ID
,LAST_UPDATED_DT
和LAST_UPDATED_BY
。
我的目标是预测最新更新的EMPLOYEE_ID
,LAST_UPDATED_DT
和LAST_UPDATED_BY
列。
以下是这些列的DDL:
create table EMPLOYEE
(
EMPLOYEE_ID INT,
NAME VARCHAR(100),
LAST_UPDATED_BY VARCHAR(200),
LAST_UPDATED_DT DATE
);
create table EMPLOYEE_AWARD
(
AWARD_ID INT,
EMPLOYEE_ID INT,
AWARD_NAME VARCHAR(100),
LAST_UPDATED_BY VARCHAR(200),
LAST_UPDATED_DT DATE
);
create table EMPLOYEE_ADDRESS
(
ADDRESS_ID INT,
EMPLOYEE_ID INT,
ADDRESS VARCHAR(100),
LAST_UPDATED_BY VARCHAR(200),
LAST_UPDATED_DT DATE
);
为了进一步说明,所以如果经理上周在{{1}}表中添加了员工记录,并且一周后添加了EMPLOYEE_AWARD,我想要检索EMPLOYEE
的最新值以及相应的LAST_UPDATE_DT
值。
简单地说,我想确定谁对员工的记录进行了最新更新(跨越多个表格。
我尝试将所有这些表合并在一起并选择LAST_UPDATED_BY
,但我无法弄清楚如何为max(LAST_UPDATED_DT)
获取正确的值。
以下是我尝试的SQL:
LAST_UPDATED_BY
我还创建了一个SQL小提琴来演示我的问题:
http://sqlfiddle.com/#!2/3b0e2/4
我感谢任何帮助。
答案 0 :(得分:3)
我有一个解决方案,但它很难看:
UNION
,last_updated_dt,last_updated_by
SELECT employee_id, last_updated_dt, last_updated_by
FROM (
SELECT employee_id, last_updated_dt, last_updated_by,
row_number() OVER (
PARTITION BY employee_id
ORDER BY last_updated_dt DESC) AS rn
FROM (
SELECT employee_id, last_updated_dt, last_updated_by
FROM EMPLOYEE
UNION ALL
SELECT employee_id, last_updated_dt, last_updated_by
FROM EMPLOYEE_AWARD
UNION ALL
SELECT employee_id, last_updated_dt, last_updated_by
FROM EMPLOYEE_ADDRESS
)
)
WHERE rn=1;
答案 1 :(得分:2)
我认为您可以将它们合并在一起,然后按降序排列last_updated_dt的输出,并将输出限制为1.
SELECT employee_id,
last_updated_dt,
last_updated_by
FROM (SELECT employee_id, last_updated_dt, last_updated_by
FROM employee
UNION
SELECT employee_id, last_updated_dt, last_updated_by
FROM employee_award
UNION
SELECT employee_id, last_updated_dt, last_updated_by
FROM employee_address
) last
WHERE employee_id = 1
ORDER BY last_updated_dt DESC
LIMIT 1
为了提高效率,您可能希望将标准放在UNION子查询中。
SELECT employee_id,
last_updated_dt,
last_updated_by
FROM (SELECT employee_id, last_updated_dt, last_updated_by
FROM employee
WHERE employee_id = 1
UNION
SELECT employee_id, last_updated_dt, last_updated_by
FROM employee_award
WHERE employee_id = 1
UNION
SELECT employee_id, last_updated_dt, last_updated_by
FROM employee_address
WHERE employee_id = 1
) last
ORDER BY last_updated_dt DESC
LIMIT 1
正如评论中正确指出的,上述解决方案仅适用于MySQL,而不适用于Oracle。这是一个应该在Oracle中运行的版本。
SELECT DISTINCT employee_id,
FIRST_VALUE(last_updated_dt) OVER (ORDER BY last_updated_dt DESC),
FIRST_VALUE(last_updated_by) OVER (ORDER BY last_updated_dt DESC)
FROM (SELECT employee_id, last_updated_dt, last_updated_by
FROM employee
WHERE employee_id = 1
UNION
SELECT employee_id, last_updated_dt, last_updated_by
FROM employee_award
WHERE employee_id = 1
UNION
SELECT employee_id, last_updated_dt, last_updated_by
FROM employee_address
WHERE employee_id = 1
)