检索跨多个表的最新更新的日期/用户

时间:2013-06-27 10:46:43

标签: sql oracle

我在Oracle数据库中有几个与员工记录相关的表。这些表中的每一个都包含三个相似的列:EMPLOYEE_IDLAST_UPDATED_DTLAST_UPDATED_BY

我的目标是预测最新更新的EMPLOYEE_IDLAST_UPDATED_DTLAST_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

我感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

我有一个解决方案,但它很难看:

    所有employee_ids的
  1. UNION,last_updated_dt,last_updated_by
  2. 使用分析函数
  3. 按last_updated_dt排序
  4. 过滤掉最新的更改
  5. 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
       )