Ako obmedziť počet riadkov vrátených dotazom Oracle po zoradení?

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 
Komentáre (6)

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.

Komentáre (3)

(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.

Komentáre (2)