Oracle의 SQL 문에 큰 문제가 있습니다. 다른 select 문에서 목록에없는 STORAGE_DB에서 주문한 TOP 10 레코드를 선택하고 싶습니다.
이것은 모든 레코드에 대해 잘 작동합니다.
SELECT DISTINCT
APP_ID,
NAME,
STORAGE_GB,
HISTORY_CREATED,
TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE
FROM HISTORY WHERE
STORAGE_GB IS NOT NULL AND
APP_ID NOT IN (SELECT APP_ID
FROM HISTORY
WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009')
하지만 내가 추가 할 때
AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC
어떤 종류의 “무작위”기록을 받고 있습니다. 주문 전에 제한이 있기 때문에 생각합니다.
누군가 좋은 해결책이 있습니까? 다른 문제 :이 쿼리는 실제로 느립니다 (10k + 레코드)
답변
아래와 같이 현재 쿼리를 하위 쿼리에 넣어야합니다.
SELECT * FROM (
SELECT DISTINCT
APP_ID,
NAME,
STORAGE_GB,
HISTORY_CREATED,
TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE
FROM HISTORY WHERE
STORAGE_GB IS NOT NULL AND
APP_ID NOT IN (SELECT APP_ID FROM HISTORY WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') ='06.02.2009')
ORDER BY STORAGE_GB DESC )
WHERE ROWNUM <= 10
Oracle 은 반환 된 결과에 rownum 을 적용 합니다.
결과가 반환 된 후 결과를 필터링해야하므로 하위 쿼리가 필요합니다. RANK () 함수를 사용하여 Top-N 결과를 얻을 수도 있습니다 .
성능을 위해 NOT EXISTS
대신 사용하십시오 NOT IN
. 자세한 내용은 이것을 참조하십시오 .
답변
Oracle 12c를 사용하는 경우 다음을 사용하십시오.
FETCH NEXT N ROWS 만 해당
SELECT DISTINCT
APP_ID,
NAME,
STORAGE_GB,
HISTORY_CREATED,
TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE
FROM HISTORY WHERE
STORAGE_GB IS NOT NULL AND
APP_ID NOT IN (SELECT APP_ID FROM HISTORY WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') ='06.02.2009')
ORDER BY STORAGE_GB DESC
FETCH NEXT 10 ROWS ONLY
추가 정보 : http://docs.oracle.com/javadb/10.5.3.0/ref/rrefsqljoffsetfetch.html
답변
성능 저하와 관련하여 여러 가지가있을 수 있으며 실제로 별도의 질문이어야합니다. 그러나 문제가 될 수있는 분명한 것이 있습니다.
WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009')
HISTORY_DATE가 실제로 날짜 열이고 인덱스가 있으면이 다시 쓰기가 더 잘 수행됩니다.
WHERE HISTORY_DATE = TO_DATE ('06.02.2009', 'DD.MM.YYYY')
데이터 유형 변환이 B- 트리 인덱스 사용을 비활성화하기 때문입니다.
답변
시험
SELECT * FROM users FETCH NEXT 10 ROWS ONLY;
답변
ORDER BY 이전에 ROWNUM이 적용 되었기 때문에 분명히 임의의 세트를 얻습니다. 따라서 쿼리는 처음 10 개의 행을 가져 와서 정렬합니다 .0 상위 10 개의 급여를 선택하려면 하위 쿼리에서 분석 함수를 사용하고 다음을 필터링해야합니다.
select * from
(select empno,
ename,
sal,
row_number() over(order by sal desc nulls last) rnm
from emp)
where rnm<=10
답변
