2014-07-03 71 views
1

我正在嘗試查找特定列的值與之前狀態不同的最新日期或版本。Oracle SQL - 查找歷史記錄表中列更改的最新數據

這裏是什麼我的歷史表看起來像一個例子:

ID_OF_THING VERSION_NUMBER DATA 
1   3    'Value2' 
1   2    'Value2' 
1   1    'Value1' 
2   3    'Value3' 
2   2    'Value2' 
2   1    'Value1' 

在這種情況下,id_of_thing 1的答案是第2版,因爲它是在以前的版本號有不同的最高版本號數據。 id_of_thing 2的答案是版本3.

我不知道如何開始在這裏。

select ID_OF_THING, MAX(VERSION_NUMBER) 
GROUP BY ID_OF_THING; 

回答

1

這是最容易分析(又名窗)函數來實現,在這種情況下,鉛()或滯後()查看:如果我只是想在最新的版本號,因爲這將是一樣簡單下一行或上一行的數據。下面應該爲你工作(替換我使用的表名(不管你叫你的表「測試」)):

select 
    id_of_thing, 
    version_with_latest_change=max(version_number) 
from (
    select 
     id_of_thing, version_number, data, 
     previous_data=lag(data) over (
      partition by id_of_thing 
      order by version_number 
     ) 
    from test 
) x 
where data <> previous_data 
group by id_of_thing 
0

參見下面的例子,我已經使用WITH語句來「模擬」你的表。實際上,只需將「tbL」替換爲您的表名並刪除WITH子句即可。

查詢查找值更改的最大版本,並使用id和版本從表中返回該行。它還涉及沒有任何更新只有一個記錄版本的情況。

WITH tbl As 
    (
    SELECT 1 As id, 3 As ver, 'Value2' As val FROM dual UNION ALL 
    SELECT 1 As id, 2 As ver, 'Value2' As val FROM dual UNION ALL 
    SELECT 1 As id, 1 As ver, 'Value1' As val FROM dual UNION ALL 
    SELECT 2 As id, 3 As ver, 'Value3' As val FROM dual UNION ALL 
    SELECT 2 As id, 2 As ver, 'Value2' As val FROM dual UNION ALL 
    SELECT 2 As id, 1 As ver, 'Value1' As val FROM dual 
    ) 
    SELECT t.* 
     FROM tbl t 
    WHERE (t.id, t.ver) IN 
    (
    SELECT z.id 
     , MAX(z.ver) As max_ver 
     FROM (SELECT x.id 
        , x.ver 
        , x.val 
        , LAG(x.val) OVER (PARTITION BY x.id ORDER BY ver) As lag_val 
        , MIN(x.ver) OVER (PARTITION BY x.id) As min_ver 
        , MAX(x.ver) OVER (PARTITION BY x.id) As max_ver 
       FROM tbl x 
      ) z 
    WHERE ((z.min_ver = z.max_ver) -- where there is only one version 
      OR (z.val != z.lag_val) -- where the value has changed 
      ) 
    GROUP BY z.id 
    ); 
相關問題