Finnes det en måte å få en Oracle
-spørring til å oppføre seg som om den inneholder en MySQL limit
-klausul?
I MySQL
kan jeg gjøre dette:
select *
from sometable
order by name
limit 20,10
for å få den 21. til den 30. raden (hopp over de første 20, gi de neste 10). Radene er valgt etter ordre etter
, så det starter virkelig på det 20. navnet alfabetisk.
I Oracle
er det eneste folk nevner pseudokolonnen rownum
, men den evalueres *før`order by
, som betyr dette:
select *
from sometable
where rownum <= 10
order by name
vil returnere et tilfeldig sett med ti rader ordnet etter navn, noe som vanligvis ikke er det jeg vil ha. Det tillater heller ikke å spesifisere en forskyvning.
Du kan bruke en underspørring for dette, for eksempel
select *
from
( select *
from emp
order by sal desc )
where ROWNUM <= 5;
Se også emnet On ROWNUM and limiting results hos Oracle/AskTom for mer informasjon.
Oppdatering: For å begrense resultatet med både nedre og øvre grenser blir ting litt mer oppblåst med
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;
(Kopiert fra spesifisert AskTom-artikkel)
Oppdatering 2: Fra og med Oracle 12c (12.1) er det en syntaks tilgjengelig for å begrense rader eller starte ved forskyvninger.
SELECT *
FROM sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
Se dette svaret for flere eksempler. Takk til Krumia for hintet.
En analytisk løsning med bare én nestet forespørsel:
SELECT * FROM
(
SELECT t.*, Row_Number() OVER (ORDER BY name) MyRow FROM sometable t
)
WHERE MyRow BETWEEN 10 AND 20;
Rank()
kan erstattes med Row_Number()
, men kan returnere flere poster enn du forventer hvis det er dupliserte verdier for name.
(uprøvd) noe som dette kan gjøre jobben
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
Det er også den analytiske funksjonen rang, som du kan bruke til å bestille etter.