Как ограничить количество строк, возвращаемых запросом Oracle после упорядочивания? - PullRequest
913 голосов
/ 22 января 2009

Есть ли способ заставить запрос Oracle вести себя так, как будто он содержит предложение MySQL limit?

В MySQL я могу сделать это:

select * 
from sometable
order by name
limit 20,10

чтобы получить 21-й по 30-й ряды (пропустите первые 20, дайте следующие 10). Строки выбираются после order by, поэтому они начинаются с 20-го имени в алфавитном порядке.

В Oracle единственное, что упоминают люди, это псевдостолбец rownum, но он оценивается до order by, что означает:

select * 
from sometable
where rownum <= 10
order by name

вернет случайный набор из десяти строк, упорядоченных по имени, что обычно не то, что я хочу. Это также не позволяет указывать смещение.

Ответы [ 14 ]

0 голосов
/ 15 октября 2018

Для каждой строки, возвращаемой запросом, псевдостолбец ROWNUM возвращает число, указывающее порядок, в котором Oracle выбирает строку из таблицы или набора соединенных строк. Первый выбранный ряд имеет ROWNUM, равный 1, второй - 2 и т. Д.

  SELECT * FROM sometable1 so
    WHERE so.id IN (
    SELECT so2.id from sometable2 so2
    WHERE ROWNUM <=5
    )
    AND ORDER BY so.somefield AND ROWNUM <= 100 

Я реализовал это на oracle сервере 11.2.0.1.0

0 голосов
/ 20 августа 2014

В оракуле

SELECT val FROM   rownum_order_test ORDER BY val DESC FETCH FIRST 5 ROWS ONLY;

VAL

    10
    10
     9
     9
     8

выбрано 5 строк.

SQL>

0 голосов
/ 18 ноября 2010

То же, что и выше с исправлениями. Работает, но определенно не красиво.

   WITH
    base AS
    (
        select *                   -- get the table
        from sometable
        order by name              -- in the desired order
    ),
    twenty AS
    (
        select *                   -- get the first 30 rows
        from base
        where rownum <= 30
        order by name              -- in the desired order
    )
    select *                       -- then get rows 21 .. 30
    from twenty
    where rownum < 20
    order by name                  -- in the desired order

Честно, лучше использовать приведенные выше ответы.

0 голосов
/ 22 января 2009

(не проверено) что-то подобное может сделать работу

WITH
base AS
(
    select *                   -- get the table
    from sometable
    order by name              -- in the desired order
),
twenty AS
(
    select *                   -- get the first 30 rows
    from base
    where rownum < 30
    order by name              -- in the desired order
)
select *                       -- then get rows 21 .. 30
from twenty
where rownum > 20
order by name                  -- in the desired order

Существует также ранг аналитической функции, который вы можете использовать для заказа.

...