2013-06-27 70 views
1

我在Oracle數據庫中有多個與員工記錄相關的表。這些表格中的每一個都包含三個相似的列:EMPLOYEE_ID,LAST_UPDATED_DTLAST_UPDATED_BY檢索日期/多個表中的最近更新的用戶

我的目標是預測最近更新的EMPLOYEE_ID,LAST_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 
); 

爲了進一步解釋,因此,如果一個經理上週增加僱員記錄到EMPLOYEE表,並在一週後增加了一個EMPLOYEE_AWARD,我想找回最近的值LAST_UPDATE_DT以及相應的LAST_UPDATED_BY值。

簡單地說,我要確定誰做的最新更新員工的記錄(其中跨多個表的跨越。

我曾試圖聯合所有這些表一起,並選擇max(LAST_UPDATED_DT),但是我想不通如何得到正確的價值LAST_UPDATED_BY

這是我嘗試的SQL:

select employee_id, max(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 
) 
latest 
where employee_id = 1 
group by employee_id; 

我也創建一個SQL小提琴來證明我的問題:

http://sqlfiddle.com/#!2/3b0e2/4

我很感激任何幫助。

回答

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 
     ) 
+0

「LIMIT」在Oracle中不能工作...... –

+0

是的,我剛剛意識到他在使用Oracle。當我去SQL Fiddle的例子,它默認爲MySQL,所以我去了那條路線。我認爲你的回答是一個很好的答案。也許在UNION子查詢中的每個查詢中輸入條件** WHERE employee_id = 1 **。 – mtwaddell

+0

「FIRST_VALUE」的+1。無論如何,當您選擇最新的日期時,我會將'UNION'更改爲'UNION ALL'。而'WHERE employee_id ='可以移出最內層的選擇,所以它只寫一次而不是三次... –

3

我有一個解決方案,但它是屁股難看:

  1. 所有employee_ids的UNION,last_updated_dt,LAST_UPDATED_BY
  2. 排序last_updated_dt與分析功能
  3. 篩選出的最新變化

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; 
相關問題