簡體   English   中英

Oracle SQL查詢:查找上次更改數據的時間

[英]Oracle SQL query : finding the last time a data was changed

我想檢索自上次更改特定列的數據以來經過的天數,例如:

TABLE_X包含

ID   PDATE        DATA1    DATA2
A    10-Jan-2013   5       10
A     9-Jan-2013   5       10
A     8-Jan-2013   5       11
A     7-Jan-2013   5       11
A     6-Jan-2013  14       12
A     5-Jan-2013  14       12
B    10-Jan-2013   3       15
B     9-Jan-2013   3       15
B     8-Jan-2013   9       15
B     7-Jan-2013   9       15
B     6-Jan-2013  14       15
B     5-Jan-2013  14        8

我出於示例目的簡化了表格。

結果應為:

ID  DATA1_LASTUPDATE  DATA2_LASTUPDATE
A   4                 2
B   2                 5

也就是說,-A最后更新的data1是4天前,-A最后更新的data2是2天前,-B最后更新的data1是2天前,-B最后更新的data2是5天前。

可以在下面使用查詢,但是如果我將其應用於具有大量記錄的真實表並添加2個以上數據列以查找其最新更新日期,則需要花費很長時間才能完成。 為此,我使用了LEAD功能。 還有其他替代方法可以加快查詢速度嗎?

with qdata1 as
(
    select ID, pdate from
    (
        select a.*, row_number() over (partition by ID order by pdate desc) rnum from
        (
            select a.*,
                   lead(data1,1,0) over (partition by ID order by pdate desc) - data1 as data1_diff
            from table_x a
        ) a
        where data1_diff <> 0
    )
    where rnum=1
),
qdata2 as
(
    select ID, pdate from
    (
        select a.*, row_number() over (partition by ID order by pdate desc) rnum from
        (
            select a.*,
                   lead(data2,1,0) over (partition by ID order by pdate desc) - data2 as data2_diff
            from table_x a
        ) a
        where data2_diff <> 0
    )
    where rnum=1
)
select a.ID,
       trunc(sysdate) - b.pdate data1_lastupdate,
       trunc(sysdate) - c.pdate data2_lastupdate,
from table_master a, qdata1 b, qdata2 c
where a.ID=b.ID(+) and a.ID=b.ID(+)
  and a.ID=c.ID(+) and a.ID=c.ID(+)

非常感謝。

您的查詢沒有為我返回正確的結果,也許我錯過了一些東西,但是下面的查詢也得到了正確的結果(您可以檢查此SQLFiddle演示 ):

with ranked as (
                  select ID, 
                         data1,
                         data2,   
                         rank() over(partition by id order by pdate desc) r 
                  from table_x
               )
select id,
       sum(DATA1_LASTUPDATE) DATA1_LASTUPDATE,
       sum(DATA2_LASTUPDATE) DATA2_LASTUPDATE
from (
     -- here I get when data1 was updated
         select id, 
                count(1) DATA1_LASTUPDATE,
                0 DATA2_LASTUPDATE
           from ranked
     start with r = 1
    CONNECT BY (PRIOR data1 = data1)
           and PRIOR r = r - 1
      group by id
    union 
  -- here I get when data2 was updated
        select id, 
               0 DATA1_LASTUPDATE,
               count(1) DATA0_LASTUPDATE  
           from ranked
     start with r = 1
    CONNECT BY (PRIOR data2 = data2)
           and PRIOR r = r - 1
      group by id
)  
group by id

您可以通過同時進行兩個滯后(或超前)計算來避免表和聯接上的多個匹配項:

with t as (
  select id, pdate, data1, data2,
    lag(data1) over (partition by id order by pdate) as lag_data1,
    lag(data2) over (partition by id order by pdate) as lag_data2
  from table_x
),
u as (
  select t.*,
    case when lag_data1 is null or lag_data1 != data1 then pdate end as pdate1,
    case when lag_data2 is null or lag_data2 != data2 then pdate end as pdate2
  from t
),
v as (
  select u.*,
    rank() over (partition by id order by pdate1 desc nulls last) as rn1,
    rank() over (partition by id order by pdate2 desc nulls last) as rn2
  from u
)
select v.id,
  max(trunc(sysdate) - (case when rn1 = 1 then pdate1 end))
    as data1_last_update,
  max(trunc(sysdate) - (case when rn2 = 1 then pdate2 end))
    as data2_last_update
from v
group by v.id
order by v.id;

假設您的意思是您的數據適用於Jun-2014 ,而不是Jan-2013 並且您正在將最新更改日期與當前日期進行比較。 調整數據以使用10-Jun-2014等,得出的結果是:

ID DATA1_LAST_UPDATE DATA2_LAST_UPDATE
-- ----------------- -----------------
A                  4                 2 
B                  2                 5 

第一個CTE( t )獲取實際的表數據,並使用lag(這與按降序排列的lead相同)添加了兩個額外的列,每個數據列一個。

第二個CTE( u )添加了兩個日期列,這些日期列僅在更改數據列時設置(或在第一次設置時,以防萬一它們從未更改過)。 因此,如果一行的data1與上一行相同,則其pdate1將為空白。 您可以通過重復計算滯后時間來合並前兩者,但我將其分開以使其更加清晰。

第三CTE( v )為這些pdate列分配排名,以使最新的列第一。

最終查詢將計算出從當前日期到每個數據列排名最高(即最新)的更改之間的差異。

SQL Fiddle包括所有CTE單獨運行,因此您可以查看它們的運行情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM