Эквиваленты SQL Server TOP

In SQL Server, TOP may be used to return the first n number of rows in a query. For example,

SELECT TOP 100 * FROM users ORDER BY id
might be used to return the first 100 people that registered for a site. (This is not necessarily the best way, I am just using it as an example).

Мой вопрос: что эквивалентно TOP в других базах данных, таких как Oracle, MySQL, PostgreSQL и т. д.? Если нет эквивалентного ключевого слова, какие обходные пути вы можете порекомендовать для достижения того же результата?


person Justin Ethier    schedule 06.05.2009    source источник
comment
Дубликат: stackoverflow.com/questions/595123/   -  person Paul Tomblin    schedule 06.05.2009
comment
Технически, да. Но только если вы знаете ключевое слово mysql LIMIT, которого я не знал в то время.   -  person Justin Ethier    schedule 05.01.2010


Ответы (8)


Чтобы выбрать первые 100 строки:

MySQL и PostgreSQL:

SELECT  *
FROM    Table
ORDER BY
        column
LIMIT 100

Oracle:

SELECT  *
FROM    (
        SELECT  t.*
        FROM    table
        ORDER BY
                column
        )
WHERE   rownum <= 100

Обратите внимание, что здесь вам нужен подзапрос. Если вы не добавите подзапрос, ROWNUM выберет первые 10 строк в случайном порядке, а затем отсортирует их по column.

Чтобы выбрать строки между 100 и 300:

MySQL:

SELECT  *
FROM    TABLE
ORDER BY
        column
LIMIT   100, 200

PostgreSQL:

SELECT  *
FROM    Table
ORDER BY
        column
OFFSET 100 LIMIT 200

Oracle:

SELECT  *
FROM    (
        SELECT  t.*, ROW_NUMBER() OVER (ORER BY column) AS rn
        FROM    table
        )
WHERE   rn >= 100
        AND rownum <= 200

Обратите внимание, что попытка упростить его с помощью ROWNUM BETWEEN 100 AND 200 (в отличие от rn BETWEEN 100 AND 200 во внешнем запросе) ничего не вернет в Oracle!

RN BETWEEN 100 AND 200 будет работать и в Oracle, но менее эффективно.

Подробнее о производительности см. в статье в моем блоге:

person Quassnoi    schedule 06.05.2009
comment
почему это не стандартизировано? то, что опубликовал @ocdecia, вообще не ясно, я думаю, что нотации mysql и postgre являются лучшими - person Pablote; 06.05.2009
comment
@Pablote: потому что Oracle старше меня, а Sybase (на которой основан SQL Server) всего на 4 года моложе. В то время не было стандартов. А к моменту появления стандартов уже существовало слишком много кода, чтобы что-то изменить. - person Quassnoi; 06.05.2009
comment
@Pablote: @ocdecio опубликовал аналитические функции, а не ограничение набора записей. Их можно использовать для ограничения наборов записей, но это не их основная цель. - person Quassnoi; 06.05.2009
comment
@Quassnoi - это правильно, но он относится к стандартным оконным функциям SQL3 и поэтому IMO лучше, чем использование конкретного синтаксиса каждого поставщика. - person Otávio Décio; 06.05.2009
comment
@ocdecio: ROW_NUMBER всегда менее неэффективен, чем ROWNUM в Oracle, а иногда менее эффективен, чем TOP в MS SQL. - person Quassnoi; 06.05.2009
comment
Не могли бы вы указать для вашего примера MySQL, что является пределом, а что смещением? - person John Fouhy; 07.05.2009

Для Postgres и MySQL это ключевое слово LIMIT.

SELECT *
  FROM users
 ORDER BY id
 LIMIT 100;
person Steve K    schedule 06.05.2009

Это стандартный SQL (его реализуют Oracle и SQL Server). Это пример возврата до 100 строк:

        SELECT ID_CONTROL FROM (SELECT ROW_NUMBER() OVER (ORDER BY ID_CONTROL) 
        ROWNUMBER, ID_CONTROL FROM IWS_CONTROL WHERE 
        CURRENT_STATE = 15 AND CURRENT_STATUS=0) A WHERE ROWNUMBER <= 100)
person Otávio Décio    schedule 06.05.2009

В SQL Anywhere это то же самое, что и в SQL Server:

SELECT TOP 100 * FROM users ORDER BY id

Вы даже можете начать с середины набора результатов, если хотите:

SELECT TOP 100 START AT 50 * FROM users ORDER BY id

получает с 50-й по 150-ю строки результирующего набора.

person Graeme Perrow    schedule 07.05.2009

Вы можете использовать RANK() и DENSE_RANK() в Oracle. здесь находится ссылка на веб-сайт AskTom, где объясняется, как для разбивки на страницы и первых n запросов с DENSE_RANK в Oracle.

person Syed Tayyab Ali    schedule 06.05.2009

Оракул:

select * from (select * from foo ORDER BY bar) where rownum < 100

С хорошим объяснением того, как заставить его работать в AskTom.

В Ingres тот же запрос будет:

select First 100 * from foo ORDER BY bar

На вопрос Ingres уже был дан ответ в StackOverflow раньше.

person Pablo Santa Cruz    schedule 06.05.2009
comment
Таким образом, запрос на самом деле должен быть таким: select * from (select * from foo order by bar), где rownum ‹100, чтобы получить первые 100 после упорядочения... - person Sean; 06.05.2009
comment
К сожалению, это должно быть ‹=100, так как rownum начинается с 1. - person Sean; 06.05.2009

В DB2 ваш запрос будет выглядеть так:

SELECT * FROM tblData ИЗВЛЕЧЬ ТОЛЬКО ПЕРВЫЕ 10 СТРОК;

person Community    schedule 06.05.2009

В Oracle вы хотите использовать запрос TOP-N.

Например:

select  *
  from  (SELECT  *
           FROM  foo
          where  foo_id=[number]
       order by  foo_id desc)
 where  rownum <= 3

Это даст вам три лучших результата (потому что я заказываю по описанию в подзапросе)

person northpole    schedule 06.05.2009