Top-N-query's en paginering komen veel voor in webapplicaties. De gebruiker voert een reeks criteria in, die een query uitvoert en de gebruiker vervolgens op de knoppen Vorige en Volgende laat klikken om door de resultatenset te bladeren. Om deze pagingfunctionaliteit te bereiken, moet de toepassing een bepaalde set rijen uit de databasequery kunnen halen.
Laten we eens kijken naar de verschillende methoden in Oracle om Top-N-query's in Oracle en paginering in Oracle-query's te bereiken
Vóór 12c
(1) ROWNUM-clausule gebruiken
Wat is ROWNUM
Het is een pseudokolom (geen echte kolom) die beschikbaar is in een zoekopdracht. ROWNUM krijgt de nummers 1, 2, 3, 4, … N toegewezen, waarbij N het aantal rijen is in de set waarmee ROWNUM wordt gebruikt. Een ROWNUM-waarde wordt niet permanent aan een rij toegewezen.
Hier is de manier om de top 5 waarden te verkrijgen
SELECT * FROM (SELECT * FROM dept ORDER BY sales DESC) WHERE ROWNUM <= 5;
Deze versie sorteert Dept op aflopende verkoop en retourneert vervolgens de eerste vijf records die het tegenkomt (de top-vijf records).
Voor paginering in orakel, als u de 5 -10 records van de Dept wilt ordenen op verkoop desc dan ga hiervoor.
SELECT a.* FROM (SELECT ROWNUM rn, b.* FROM ( SELECT * FROM dept ORDER BY sales dsc) b where rn <=10) a WHERE a.rn >= 5
De algemene syntaxis zou zijn
select * from ( select rownum rnum, a.* from (your_query) a where rownum <= M ) where rnum >= N;
(2) ROW_NUMBER() orakelanalysefunctie gebruiken:deze gedraagt zich op dezelfde manier als de ROWNUM-pseudokolom, maar is flexibeler en heeft meer mogelijkheden
Hier is de manier om de top 5 waarden te verkrijgen
SELECT * FROM (SELECT d.*,row_number() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Hier is de vraag voor Paginering
SELECT * FROM ( SELECT d.*, row_number() over (ORDER BY d.sales DSC) rn FROM dept d) WHERE rn BETWEEN 0 AND 5 ORDER BY rn;
De bovenstaande Top N-query's zullen verschillende records opleveren wanneer twee dingen gelijk zijn voor de plek bij het gebruik van de top n-query's
(3) Met behulp van RANK() en DENSE_RANK():Dit zijn analytische functies die kunnen worden gebruikt om het hierboven genoemde probleem op te lossen
Hier is de manier om de top 5 waarden te verkrijgen met behulp van rank
SELECT * FROM (SELECT d.*,rank() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Hier is de manier om de top 5 waarden te verkrijgen met behulp van density_rank
SELECT * FROM (SELECT d.*,dense_rank() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Met 12c
Top-N-functie :
Oracle Database 12c biedt ondersteuning voor de ANSI-standaard FETCH FIRST/NEXT- en OFFSET-clausules, die samen de rijbeperkingsclausule worden genoemd. Met deze clausule kunt u eenvoudig de eerste N-records uit een resultatenset ophalen of, als alternatief, de eerste N-records nadat u een set records hebt overgeslagen, zodat u gemakkelijk door een resultatenset kunt pagineren
Met een Top-N-query kunnen we de bovenste of onderste N-rijen ophalen uit een geordende set. Door twee Top-N-query's te combineren, kunt u door een geordende set bladeren
Voorbeeld:
SELECT value FROM mytable ORDER BY value DESC FETCH FIRST 10 ROWS ONLY; select * from my_test order by name fetch first 3 rows only;
Als je naar het optimalisatieplan voor de bovenstaande query kijkt, gebruikt het nog steeds row_number() onder de wrap om het te doen
Paginering kan ook gebeuren met deze functie met de offset-syntaxis gebruiken
– offset 10 rijen halen alleen de eerste 10 rijen op
select * from my_test order by id offset 10 rows fetch next 10 rows only;
– offset 10 rijen halen alleen de eerste rijen van 0,1 procent op
select * from my_test order by id offset 10 rows first 0.1 percent rows only;
– offset 10 rijen halen eerste 3 rijen met banden. Dit betekent dat alle bovenste rijen met stropdassen ook in het resultaat worden opgenomen
select * from my_test order by name fetch first 3 rows with ties;
Als u het optimalisatieplan van de bovenstaande query controleert, zult u zien dat de optimizer de functie rank() gebruikt, zoals hierboven aangetoond in het geval Pre 12c
Beperking
(1)Als u een SELECT-instructie met FOR UPDATE hebt, kunt u deze niet gebruiken.
(2)De SELECT-instructie kan niet CURRVAL of NEXTVAL van reeksen
(3) Als de query van de gematerialiseerde weergaven deze clausule heeft, dan kunt u die gematerialiseerde weergave niet incrementeel vernieuwen
Ik hoop dat je het artikel over Top-N Queries in Oracle en Paginering in Oracle Queries leuk vindt. Geef alsjeblieft feedback
Leest ook
Lead-functie in Oracle
RANK-functie in Oracle
https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljoffsetfetch.html