簡體   English   中英

使用LAG / LEAD分析功能優化自聯接Oracle SQL查詢?

[英]Optimize self-join Oracle SQL query with LAG/LEAD analytic functions?

我們有一個Oracle SQL查詢來識別表列值從一個記錄更改為另一個記錄的記錄。 相關列是(ID,SOME_COLUMN,FROM_DATE,TO_DATE),其中ID並非唯一,而FROM_DATE和TO_DATE確定該ID的特定行生效的時間間隔,即

(ID1, VAL1, 01/01/2016, 03/01/2016)
(ID1, VAL2, 04/01/2016, 09/01/2016)
(ID1, VAL3, 10/01/2016, 19/01/2016) 

等等

我們可以使用以下自連接來實現

SELECT N.ID
       O.SOME_COLUMN OLD_VALUE,
       N.SOME_COLUMN NEW_VALUE
FROM OUR_TABLE N, OUR_TABLE O
WHERE N.ID = O.ID
  AND N.FROM_DATE - 1 = O.TO_DATE
  AND N.SOME_COLUMN <> O.SOME_COLUMN

但是,由於該表包含1億條記錄,因此性能相當不錯。 有沒有更有效的方法可以做到這一點? 有人暗示了分析功能(例如LAG),但到目前為止我們還無法找到可行的解決方案。 任何想法,將不勝感激

是的,您可以使用LEAD()來獲取最后一個值:

SELECT t.id,
       t.some_column as OLD_VALUE,
       LEAD(t.some_column) OVER(PARTITION BY t.id ORDER BY t.from_date) as NEW_VALUE
FROM YourTable t

如果您只想更改,請用另一個選擇包裝它並過濾OLD_VALUE <> NEW_VALUE

如果要將舊值和新值放在一行中,請使用lag()

select t.*,
       lag(some_column) over (partition by id order by from_date) as prev_val
from t;

如果值可能不變(如示例查詢所建議):

select t.*
from (select t.*,
             lag(some_column) over (partition by id order by from_date) as prev_val
      from t
     ) t
where prev_val <> some_column;

我認為這是您正在談論的LAG()方法。

SELECT * 
  FROM (
    SELECT ID
           N.SOME_COLUMN NEW_VALUE,
           N.FROM_DATE,
           lag(N.SOME_COLUMN) over (partition by N.ID order by FROM_DATE) OLD_VALUE,
           lag(N.TO_DATE) over (partition by N.ID order by FROM_DATE) OLD_TO_DATE,
    FROM OUR_TABLE N
) T
WHERE FROM_DATE - 1 = OLD_TO_DATE
  AND NEW_VALUE<> OLD_VALUE;

暫無
暫無

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

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