2015-01-22 3 views
4

테이블에서 최신 행만 반환하는 쿼리를 시도하고 있습니다.오라클 rownum이 잘못된 결과를 반환합니다.

처음에는 쿼리에서 max (id)를 사용했습니다. 하지만 시퀀스를 사용하고 내 envoirnment가 클러스터되어 있기 때문에 순서가 잘못된 것으로 의존 할 수 없습니다. 그래서 생성 시간을 기준으로 주문하고 rownum을 사용하여 상단 행을 선택하기로 결정했습니다.

내가

SELECT A.id 
    FROM Table_A, Table_B B 
    WHERE A.status = 'COMPLETED' 
    AND B.name = 'some_name' 
    AND A.id = B.id 
    AND rownum = 1 
    order by A.Creation_Time; 

같은 것을 사용이 어떤 방법을 반환 내가 최고 기록이 전혀 다른됩니다 condtn ROWNUM을 제거 45343을 말한다면 나 일부 잘못된 결과가 42145. 말;

+1

의심되는 경우 매뉴얼을 읽으십시오. 그곳에 모두 설명되어 있습니다. https://docs.oracle.com/cd/E11882_01/server.112/e41084/pseudocolumns009.htm#SQLRF00255 –

답변

8

rownumorder by과 함께 사용하는 경우 하위 쿼리를 사용해야합니다. 이것은 whereorder by의 평가 순서와 관련이 있습니다. 그래서,이 시도 :

SELECT t.* 
FROM (SELECT A.id 
     FROM Table_A JOIN 
      Table_B B 
      ON A.id = B.id 
     WHERE A.status = 'COMPLETED' AND B.name = 'some_name' 
     ORDER BY A.Creation_Time 
    ) ab 
WHERE rownum = 1; 

내가 추가해야합니다 : 오라클 (12)가 더 편리하다, fetch first 1 row only를 지원합니다 : 당신이 의미

SELECT A.id 
    FROM Table_A JOIN 
     Table_B B 
     ON A.id = B.id 
    WHERE A.status = 'COMPLETED' AND B.name = 'some_name' 
    ORDER BY A.Creation_Time 
    FETCH FIRST 1 ROW ONLY; 
+0

감사합니다. 이것은 기대했던대로 작동했으며 내림차순으로 주문해야했습니다. – Aditya

-1

가능성은이 작업을 수행? (DESC 주문 지정)

SELECT A.id 
    FROM Table_A, Table_B B 
    WHERE A.status = 'COMPLETED' 
    AND B.name = 'some_name' 
    AND A.id = B.id 
    AND rownum = 1 
    order by A.Creation_Time DESC; 

EDIT : 분명히 주문 DESC를 지정하는 것이 쿼리에 중요합니다. 나는 Gordon을 upvote해야만했다. 왜냐하면 그는 정렬 후에 반환되는 행을 제한해야한다는 것이 완전히 맞았 기 때문에, 그가 제안한 방법은 완벽하다. 그래서, 지금까지이 글을 읽는 분들은 rownum이 where 절이 처리 된 후에 sorting이나 aggregation (source) 전에 할당되었다는 것을 분명히하고 싶었습니다.

NB : Gordon의 답처럼, 여기에서 중요한 요소 일 수도 있고 없을 수도있는 고려 사항이 더 있습니다. A.Creation_Time 값이 중복 될 수 있으므로 쿼리를 실행할 때 중복 행이 반환 될 수있는 한 비 결정적 동작을 볼 수 있습니다. 이 문제가 발생할 수있는 경우 Tom Kyte (이전 링크와 동일한 링크)에서는 order by 절에 고유 한 열 값을 쉽게 피하는 방법을 제안합니다. 예 :

SELECT t.id 
FROM (SELECT * 
     FROM (SELECT A.id, A.Creation_Time 
      FROM Table_A A 
      JOIN Table_B B 
      ON A.id = B.id 
      WHERE A.status = 'COMPLETED' AND B.name = 'some_name' 
      ) 
     ORDER BY Creation_Time, rowid DESC 
    ) t 
WHERE rownum = 1; 

여기서 ROWID는 목적을 달성 할 수있는 고유 한 의사 열입니다.

관련 문제