2016-09-14 5 views
0

テーブル列の値があるレコードから別のレコードに変更されたレコードを識別するOracle SQLクエリがあります。関連する列は、(ID、SOME_COLUMN、FROM_DATE、TO_DATE)IDが一意でない、そしてFROM_DATEとTO_DATEは、そのIDのために特定の行が有効であったインターバルする時間を決定する、すなわち自己結合Oracle SQLクエリをLAG/LEAD分析関数で最適化しますか?

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

等です

我々は、テーブルのレコードの100百万人が含まれているので、それはかなりのパフォーマンスを打つ、次の自己結合が

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 

を使ってこれを実装することができます。これを行うより効果的な方法はありますか?誰かが分析機能(LAGなど)を暗示していましたが、これまでのところ解決策を見つけられませんでした。すべてのアイデアは、はい、あなたは最後の値を取得するためにLEAD()を使用することができます

+0

質問が不明です。あなたの日付はまったく重複しないので、あなたが望む結果が不明です。 –

+0

日付は実際には重複していません。時間間隔を表しており、その間にそのIDに属する特定のテーブル行が有効です。この例でわかるように、区間のFROM_DATEは、前の区間のTO_DATEに常に+1されます。 SOME_COLUMNの値が1つのインターバルから別のインターバルに変更された結果が必要です。実際にあなたの下の答えをチェックすることは、すべてを正しく解釈したようです。 – hammerfest

答えて

2

をいただければ幸いです。

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

1

とそれを包みます古い値と一列に新しい価値、そして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; 
1

これは、あなたが話していた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; 
+1

ありがとうございます。 3つのほとんど同じ答え、私はここに受け入れマークを入れた。 – hammerfest

+0

@hammerfest。 。 。実際には、これは第3の答えでした。あなたの推理によって、サギの答えを受け入れるべきです。名前の上に「時間」を重ねると(今は「2時間前に答えました」)、答えの正確な時刻が表示されます。 –

+0

あなたが正しいと思われる、私は単純にソリューションを試して質問ページに戻った後、2つの答えを誤って変更しました。今すぐ承諾マークを変更しました。 @vercelli:申し訳ありませんが、あなたの答えも正しいですが、それは確かに最初のものではありませんでした。 – hammerfest

関連する問題