Oracle SELECT TOP 10 records



у меня большая проблема с оператором SQL в Oracle. Я хочу выбрать 10 лучших записей, упорядоченных STORAGE_DB, которые не находятся в списке из другого оператора select.



этот отлично работает для всех записей:



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


Я получаю какие-то" случайные " записи. Я думаю, потому что предел имеет место до заказа.



есть ли у кого-то есть хорошее решение? Другая проблема: этот запрос очень медленно (10к+ записей)

1248   6  

6 ответов:

вам нужно будет поместить ваш текущий запрос в подзапрос, как показано ниже:

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 в итоге после того, как он был возвращен.
вам нужно отфильтровать Результат после его возврата, поэтому требуется подзапрос. Вы также можете использовать ранг() функция для получения топ-N результатов.

Для повышения производительности попробуйте использовать NOT EXISTS на месте NOT IN. Смотрите этой дополнительные.

что касается плохой работы, есть любое количество вещей, это может быть, и он действительно должен быть отдельный вопрос. Однако есть одна очевидная вещь, которая может быть проблемой:

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-дерева.

Если вы используете Oracle 12c, используйте:

FETCH NEXT N В СТРОКЕ

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

вы получаете явно случайный набор, потому что ROWNUM применяется перед порядком BY. Поэтому ваш запрос берет первые десять строк и сортирует их.0 для выбора десяти лучших зарплат вы должны использовать аналитическую функцию в подзапросе, а затем отфильтровать это:

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

попробовать Выберите * из пользователей только следующие 10 строк;

вы можете просто использовать TOP Clause

ВЫБЕРИТЕ TOP 10 * ИЗ ТАБЛИЦЫ;

или

выберите column_name(s) From имя_таблицы Где ROWNUM

Comments

    Ничего не найдено.