programing tip

Oracle SELECT TOP 10 레코드

itbloger 2020. 7. 15. 07:49
반응형

Oracle SELECT TOP 10 레코드


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') 

If HISTORY_DATE really is a date column and if it has an index then this rewrite will perform better:

WHERE HISTORY_DATE = TO_DATE ('06.02.2009', 'DD.MM.YYYY')  

This is because a datatype conversion disables the use of a B-Tree index.


try

SELECT * FROM users FETCH NEXT 10 ROWS ONLY;

You get an apparently random set because ROWNUM is applied before the ORDER BY. So your query takes the first ten rows and sorts them.0 To select the top ten salaries you should use an analytic function in a subquery, then filter that:

 select * from 
     (select empno,
             ename,
             sal,
             row_number() over(order by sal desc nulls last) rnm
    from emp) 
 where rnm<=10

참고URL : https://stackoverflow.com/questions/2498035/oracle-select-top-10-records

반응형