복붙노트

[SQL] 어떻게 제대로 오라클 ORDER BY와 ROWNUM을 사용 하는가?

SQL

어떻게 제대로 오라클 ORDER BY와 ROWNUM을 사용 하는가?

나는 그것으로 우리의 제품은 호환이 오라클에 SQL 서버에서 저장 프로 시저를 변환하는 힘든 시간을 보내고 있어요.

나는 타임 스탬프에 따라 일부 테이블의 가장 최근의 기록을 반환하는 쿼리를 가지고 :

SQL 서버 :

SELECT TOP 1 *
FROM RACEWAY_INPUT_LABO
ORDER BY t_stamp DESC

=> 그 뜻을 반환 나를 가장 최근의 기록

그러나 오라클 :

SELECT *
FROM raceway_input_labo 
WHERE  rownum <= 1
ORDER BY t_stamp DESC

=> 그 뜻을 반환 나에게 문 BY 가장 오래된 레코드 (아마도 인덱스에 따라)에 관계없이 주문!

나는 오라클 쿼리 내 요구 사항을 충족하기 위해이 방법을 캡슐화 :

SELECT * 
FROM 
    (SELECT *
     FROM raceway_input_labo 
     ORDER BY t_stamp DESC)
WHERE  rownum <= 1

그것은 작동합니다. 그러나 내가 관여 테이블의 레코드를 많이 가지고 특히, 나에게 끔찍한 해킹처럼 들린다.

이를 달성하는 가장 좋은 방법은 무엇입니까?

해결법

  1. ==============================

    1.를 Where 문에 의해 순서 전에 실행됩니다. 그래서, 원하는 쿼리는 "첫 번째 행을 다음 t_stamp 내림차순하여 주문"말하고있다. 그리고 당신이하려는 것이 아니다.

    를 Where 문에 의해 순서 전에 실행됩니다. 그래서, 원하는 쿼리는 "첫 번째 행을 다음 t_stamp 내림차순하여 주문"말하고있다. 그리고 당신이하려는 것이 아니다.

    하위 쿼리 방법은 오라클에서이 작업을 수행하는 적절한 방법이다.

    당신이 두 서버 모두에서 작동하는 버전을 원한다면, 당신은 사용할 수 있습니다 :

    select ril.*
    from (select ril.*, row_number() over (order by t_stamp desc) as seqnum
          from raceway_input_labo ril
         ) ril
    where seqnum = 1
    

    외부 * 마지막 열에서 "1"을 반환합니다. 이를 방지하기 위해 개별적으로 열을 나열해야합니다.

  2. ==============================

    2.사용 ROW_NUMBER () 대신. ROWNUM은 의사 열 및 ROW_NUMBER는 () 함수이다. 당신은 그들 사이의 차이에 대해 읽기 및 질의 아래의 출력의 차이를 볼 수 있습니다

    사용 ROW_NUMBER () 대신. ROWNUM은 의사 열 및 ROW_NUMBER는 () 함수이다. 당신은 그들 사이의 차이에 대해 읽기 및 질의 아래의 출력의 차이를 볼 수 있습니다

    SELECT * FROM (SELECT rownum, deptno, ename
               FROM scott.emp
            ORDER BY deptno
           )
     WHERE rownum <= 3
     /
    
    ROWNUM    DEPTNO    ENAME
    ---------------------------
     7        10    CLARK
     14       10    MILLER
     9        10    KING
    
    
     SELECT * FROM 
     (
      SELECT deptno, ename
           , ROW_NUMBER() OVER (ORDER BY deptno) rno
      FROM scott.emp
     ORDER BY deptno
     )
    WHERE rno <= 3
    /
    
    DEPTNO    ENAME    RNO
    -------------------------
    10    CLARK        1
    10    MILLER       2
    10    KING         3
    
  3. ==============================

    3.나는이 사용 사례에서 제안하는 또 다른 예를 들면 ... 최신 행을 얻기 위해 MAX (t_stamp)를 사용하는 것입니다

    나는이 사용 사례에서 제안하는 또 다른 예를 들면 ... 최신 행을 얻기 위해 MAX (t_stamp)를 사용하는 것입니다

    select t.* from raceway_input_labo t
    where t.t_stamp = (select max(t_stamp) from raceway_input_labo) 
    limit 1
    

    내 코딩 패턴 환경 (아마도) - 신뢰할 수있는, 일반적으로 수행 또는 더 나은 정렬 된 목록에서 첫번째 행을 선택하는 것보다에서 - 또한 의도를 더 명확하게 읽을 수 있습니다. 도움이 되었기를 바랍니다 ...

    SQLer

  4. ==============================

    4.위의 댓글이 디자인 문제의 커플을 문서화. 짧은 이야기는, 오라클에, 당신은 당신이 동일한 열 이름을 가진 큰 테이블 및 / 또는 테이블이있을 때 수동으로 결과를 제한 할 필요가 (당신은 명시 적 유형 모두 밖으로 원하는 모든 이들의 이름을 변경하지 마십시오). 쉬운 솔루션은 쿼리에서 것을 중단 점과 한계를 파악하는 것입니다. 당신이 충돌 열 이름 제약 조건이없는 경우 또는 당신은 또한 내부 쿼리에서이 작업을 수행 할 수 있습니다. 예를 들면

    위의 댓글이 디자인 문제의 커플을 문서화. 짧은 이야기는, 오라클에, 당신은 당신이 동일한 열 이름을 가진 큰 테이블 및 / 또는 테이블이있을 때 수동으로 결과를 제한 할 필요가 (당신은 명시 적 유형 모두 밖으로 원하는 모든 이들의 이름을 변경하지 마십시오). 쉬운 솔루션은 쿼리에서 것을 중단 점과 한계를 파악하는 것입니다. 당신이 충돌 열 이름 제약 조건이없는 경우 또는 당신은 또한 내부 쿼리에서이 작업을 수행 할 수 있습니다. 예를 들면

    WHERE m_api_log.created_date BETWEEN TO_DATE('10/23/2015 05:00', 'MM/DD/YYYY HH24:MI') 
                                     AND TO_DATE('10/30/2015 23:59', 'MM/DD/YYYY HH24:MI')  
    

    실질적 결과를 줄이려고한다. 그럼 당신은 ORDER BY 수 또는 제한 행에 대한 외부 쿼리를 않습니다.

    또한, 나는 두꺼비가 제한 행에 기능을 가지고 있다고 생각; 하지만, 반드시 오라클의 실제 쿼리 내에서 제한하지 않습니다 그. 확실하지 않다.

  5. from https://stackoverflow.com/questions/15091849/how-to-use-oracle-order-by-and-rownum-correctly by cc-by-sa and MIT license