2016-09-14 6 views
0

테이블 열의 값이 한 레코드에서 다른 레코드로 변경된 레코드를 식별하는 Oracle SQL 쿼리가 있습니다. 관련 컬럼은 (ID, SOME_COLUMN, FROM_DATE, TO_DATE)에 ID가 고유하지 않으며, FROM_DATE과 TO_DATE 등 즉, 그 ID에 대한 특정 행 효과적되는 시간 간격LAG/LEAD 분석 함수를 사용하여 자체 조인 Oracle SQL 쿼리를 최적화 하시겠습니까?

(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)를 암시하는 사람이 있었지만 지금까지 해결 방법을 찾지 못했습니다.

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

+0

질문이 명확하지 않습니다. 귀하의 날짜는 전혀 중복되지 않으며 원하는 결과가 확실하지 않습니다. –

+0

날짜는 실제로 겹치지 않습니다. 이는 해당 ID에 속하는 특정 테이블 행이 효과적이었던 시간 간격을 나타냅니다. 이 예에서 보는 것처럼 간격의 FROM_DATE는 항상 이전 간격의 TO_DATE에 +1이 추가됩니다. SOME_COLUMN 값이 한 간격에서 다른 간격으로 변경된 결과가 필요합니다. 실제로 아래 답변을 확인하면 모든 것을 올바르게 해석 한 것 같습니다. – hammerfest

답변

2

을 감상 할 수있다 이전 값과 단일 행에 새 값, 다음 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

필터 : 모든 아이디어 네, 마지막 값을 가져 LEAD()을 사용할 수 있습니다

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

고맙습니다. 거의 동일한 세 가지 답변 중 첫 번째로 동의 마크를 여기에 표시했습니다. – hammerfest

+0

@hammerfest. . . 사실, 이것은 세 번째 대답이었습니다. 당신의 추론에 따라 사기의 대답을 받아 들여야합니다. 이름 위에 "시간"을 올려 놓으면 (지금 "2 시간 전에 답변 됨") 정확한 답변 시간을 볼 수 있습니다. –

+0

당신이 옳았다 고 생각합니다. 솔루션을 시험하고 질문 페이지로 돌아온 후에 두 가지 대답을 단순히 변경했습니다. 지금 동의 표시를 변경했습니다. @vercelli : 죄송합니다. 귀하의 답변도 정확 합니다만 실제로는 첫 번째 답변이 아닙니다. – hammerfest