Oracle ORDER BY 및 ROWNUM을 올바르게 사용하는 방법
당사 제품과 호환되도록 저장 프로시저를 SQL Server에서 Oracle로 변환하는 데 어려움을 겪고 있습니다.
타임스탬프에 따라 일부 테이블의 최신 레코드를 반환하는 쿼리가 있습니다.
SQL Server:
SELECT TOP 1 *
FROM RACEWAY_INPUT_LABO
ORDER BY t_stamp DESC
=> 그러면 최신 레코드가 반환됩니다.
그러나 Oracle:
SELECT *
FROM raceway_input_labo
WHERE rownum <= 1
ORDER BY t_stamp DESC
=> 그러면 가장 오래된 레코드(인덱스에 따라 다름)가 반환됩니다.ORDER BY스테이트먼트!
요건을 충족하기 위해 Oracle 쿼리를 다음과 같이 캡슐화했습니다.
SELECT *
FROM
(SELECT *
FROM raceway_input_labo
ORDER BY t_stamp DESC)
WHERE rownum <= 1
그리고 그것은 동작한다.하지만 제게는 끔찍한 해킹처럼 들리는데요, 특히 제가 관련 테이블에 많은 기록을 가지고 있다면요.
이것을 달성하는 가장 좋은 방법은 무엇입니까?
그where스테이트먼트가 실행되기 전에order by원하는 질문은 "첫 번째 행을 선택한 후 다음 순서로 주문합니다. t_stamp desc"라고 써있네요.그건 당신이 의도한 바가 아니에요.
이 작업을 수행하려면 오라클에서 하위 쿼리 방법을 사용하는 것이 좋습니다.
두 서버에서 모두 사용할 수 있는 버전을 원하는 경우 다음을 사용할 수 있습니다.
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"이 반환됩니다.이 문제를 방지하려면 열을 개별적으로 나열해야 합니다.
사용하다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
Oracle 12c 이후 행 제한 절을 사용하여 이 작업을 수행할 수 있게 되었습니다.
SELECT *
FROM raceway_input_labo
ORDER BY t_stamp DESC
FETCH FIRST ROW ONLY
또는 다양한 시나리오(처음 n행, 동점 처리 등)에 대한 많은 대안.
상기의 코멘트로, 이것에 관한 몇개의 설계상의 문제를 문서화합니다.요약하자면, Oracle에서는 열 이름이 같은 큰 테이블 및/또는 테이블이 있는 경우(또한 모두 명시적으로 입력하고 이름을 변경하지 않으려면) 결과를 수동으로 제한해야 합니다.간단한 해결책은 중단점을 파악하여 쿼리에서 이를 제한하는 것입니다.또는 충돌하는 열 이름 제약 조건이 없는 경우 내부 조회에서도 이 작업을 수행할 수 있습니다.예.
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를 사용하거나 외부 쿼리를 수행하여 행을 제한할 수 있습니다.
또한 TOAD에는 행을 제한하는 기능이 있다고 생각합니다만, Oracle의 실제 쿼리 내에서 제한되는지는 확실하지 않습니다.확실하진 않다.
이 사용 예에서는 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
언급URL : https://stackoverflow.com/questions/15091849/how-to-use-oracle-order-by-and-rownum-correctly
'codememo' 카테고리의 다른 글
| --eslint를 사용해도 오류는 수정되지 않습니다. (0) | 2023.02.22 |
|---|---|
| 반응 JS onClick 이벤트 핸들러 (0) | 2023.02.22 |
| 각도 UI 라우터가 비동기 데이터를 해상도로 가져옵니다. (0) | 2023.02.16 |
| Android에서 json 생성 (0) | 2023.02.16 |
| Woocommerce 3+에서 라인 항목을 사용하여 프로그래밍 방식으로 주문 작성 (0) | 2023.02.16 |