Existuje spôsob, ako dosiahnuť, aby sa dotaz Oracle
správal tak, ako keby obsahoval klauzulu MySQL limit
?
V MySQL
to môžem urobiť:
select *
from sometable
order by name
limit 20,10
získať 21. až 30. riadok (vynechať prvých 20, dať ďalších 10). Riadky sa vyberajú za order by
, takže sa naozaj začína na 20. mene podľa abecedy.
V Oracle
ľudia spomínajú iba pseudoslúpec rownum
, ale ten sa vyhodnocuje pred order by
, čo znamená toto:
select *
from sometable
where rownum <= 10
order by name
vráti náhodnú sadu desiatich riadkov usporiadaných podľa mena, čo zvyčajne nie je to, čo chcem. Taktiež neumožňuje špecifikovať posun.
Môžete na to použiť poddotaz, ako napríklad
select *
from
( select *
from emp
order by sal desc )
where ROWNUM <= 5;
Pozrite si tiež tému On ROWNUM and limiting results na Oracle/AskTom, kde nájdete ďalšie informácie.
Aktualizácia: Na obmedzenie výsledku pomocou dolných aj horných hraníc sa veci trochu viac nafúknu pomocou
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;
(Skopírované z uvedeného AskTom-článku)
Aktualizácia 2: Počnúc verziou Oracle 12c (12.1) je k dispozícii syntax na obmedzenie riadkov alebo začiatok v offsete.
SELECT *
FROM sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
Viac príkladov nájdete v tejto odpovedi. Za nápovedu ďakujeme Krumia.
Analytické riešenie len s jedným vnoreným dotazom:
SELECT * FROM
(
SELECT t.*, Row_Number() OVER (ORDER BY name) MyRow FROM sometable t
)
WHERE MyRow BETWEEN 10 AND 20;
Rank()
by mohol byť nahradený Row_Number()
, ale môže vrátiť viac záznamov, ako očakávate, ak existujú duplicitné hodnoty pre meno.
(neotestované) niečo také by mohlo splniť svoju úlohu
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
Existuje aj analytická funkcia rank, ktorú môžete použiť na usporiadanie podľa.