Има ли начин да накарате заявка на 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
ще върне произволен набор от десет реда, подредени по име, което обикновено не е това, което искам. Освен това не позволява да се зададе отместване.
За целта можете да използвате подзапитване, например
select *
from
( select *
from emp
order by sal desc )
where ROWNUM <= 5;
Разгледайте също темата On ROWNUM and limiting results в Oracle/AskTom за повече информация.
Актуализация: За ограничаване на резултата с долни и горни граници нещата стават малко по-раздути с
select * from
( select a.*, ROWNUM rnum from
( <your_query_goes_here, with order by> ) a
where ROWNUM <= :MAX_ROW_TO_FETCH )
where rnum >= :MIN_ROW_TO_FETCH;
(Копирано от посочената AskTom-статия)
Актуализация 2: От Oracle 12c (12.1) е наличен синтаксис за ограничаване на редове или започване на отмествания.
SELECT *
FROM sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
Вижте този отговор за повече примери. Благодаря на Крумия за подсказката.
Аналитично решение само с една вложена заявка:
SELECT * FROM
(
SELECT t.*, Row_Number() OVER (ORDER BY name) MyRow FROM sometable t
)
WHERE MyRow BETWEEN 10 AND 20;
Rank()
може да се замени с Row_Number()
, но може да върне повече записи, отколкото очаквате, ако има дублирани стойности за име.
(не е тествано) нещо подобно може да свърши работа
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
Съществува и аналитичната функция rank, която можете да използвате за подреждане по.