Oracle SQL--查找历史记录表中某列发生更改的最新数据
我试图找到某列的值与前一状态不同的最新日期或版本 下面是我的历史记录表的示例:Oracle SQL--查找历史记录表中某列发生更改的最新数据,sql,oracle,window,Sql,Oracle,Window,我试图找到某列的值与前一状态不同的最新日期或版本 下面是我的历史记录表的示例: ID_OF_THING VERSION_NUMBER DATA 1 3 'Value2' 1 2 'Value2' 1 1 'Value1' 2 3 'Value3' 2 2
ID_OF_THING VERSION_NUMBER DATA
1 3 'Value2'
1 2 'Value2'
1 1 'Value1'
2 3 'Value3'
2 2 'Value2'
2 1 'Value1'
在本例中,_thing 1的id_的答案是版本2,因为它是最高的版本号,以前的版本号具有不同的数据。_thing 2的id_的答案是版本3
我甚至不知道如何在这里开始。如果我只想要最新的版本号,它将非常简单:
select ID_OF_THING, MAX(VERSION_NUMBER)
GROUP BY ID_OF_THING;
使用分析窗口函数最容易做到这一点,在本例中,查看下一行或上一行的数据是超前或滞后的。以下内容适用于将我使用的test表名替换为您所称的表名:
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
请参见下面的示例,其中我使用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
);