Top-N-forespørgsler og sideinddeling er almindelige i webbaserede applikationer. Brugeren indtaster et sæt kriterier, som kører en forespørgsel og derefter lader brugeren klikke på knapperne Forrige og Næste for at bladre gennem resultatsættet. For at opnå denne personsøgningsfunktionalitet skal applikationen være i stand til at hente et bestemt sæt rækker fra databaseforespørgslen.
Lad os tage et kig på de forskellige metoder i Oracle til at opnå Top-N-forespørgsler i Oracle og sideinddeling i Oracle-forespørgsler
Pre 12c
(1) Brug af ROWNUM-klausul
Hvad er ROWNUM
Det er en pseudokolonne (ikke en rigtig kolonne), der er tilgængelig i en forespørgsel. ROWNUM vil blive tildelt tallene 1, 2, 3, 4, … N , hvor N er antallet af rækker i det sæt ROWNUM bruges med. En ROWNUM-værdi tildeles ikke permanent til en række .
Her er vejen til at opnå de 5 bedste værdier
SELECT * FROM (SELECT * FROM dept ORDER BY sales DESC) WHERE ROWNUM <= 5;
Denne version vil sortere afd. efter salg faldende og derefter returnere de første fem poster, den støder på (de top-fem poster).
For paginering i oracle, hvis du vil have de 5 -10 poster for afdelingsordren efter salgsbeskrivelse, så gå efter dette.
SELECT a.* FROM (SELECT ROWNUM rn, b.* FROM ( SELECT * FROM dept ORDER BY sales dsc) b where rn <=10) a WHERE a.rn >= 5
Den generelle syntaks ville være
select * from ( select rownum rnum, a.* from (your_query) a where rownum <= M ) where rnum >= N;
(2) Brug af ROW_NUMBER() oracle analytisk funktion:Den opfører sig på samme måde som ROWNUM pseudo kolonnen, men er mere fleksibel og har flere muligheder
Her er vejen til at opnå de 5 bedste værdier
SELECT * FROM (SELECT d.*,row_number() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Her er forespørgslen til sideinddeling
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;
Ovenstående Top N-forespørgsler vil give returnering forskellige poster, når to ting er uafgjort, når du bruger de øverste n-forespørgsler
(3) Brug af RANK() og DENSE_RANK():Disse er analytiske funktioner, som kan bruges til at fjerne problemet nævnt ovenfor
Her er måden at opnå de 5 bedste værdier ved at bruge rang
SELECT * FROM (SELECT d.*,rank() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Her er måden at opnå de 5 bedste værdier ved at bruge dense_rank
SELECT * FROM (SELECT d.*,dense_rank() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Med 12c
Top-N-funktion :
Oracle Database 12c inkluderer understøttelse af ANSI-standarden FETCH FIRST/NEXT og OFFSET-sætninger – tilsammen kaldet rækkebegrænsende klausul. Denne klausul giver dig mulighed for nemt at hente de første N poster fra et resultatsæt eller alternativt de første N poster efter at have springet over et sæt poster, så du nemt kan paginere gennem et resultatsæt
En Top-N-forespørgsel giver os mulighed for at hente de øverste eller nederste N rækker fra et bestilt sæt. Ved at kombinere to Top-N-forespørgsler får du mulighed for at bladre gennem et bestilt sæt
Eksempel:
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;
Hvis du ser på optimeringsplanen for ovenstående forespørgsel, bruger den stadig row_number() til at gøre det
Sideinddeling kan også ske med denne funktion med brug af offset-syntaks
– offset 10 rækker henter kun de første 10 rækker
select * from my_test order by id offset 10 rows fetch next 10 rows only;
– offset 10 rækker henter kun de første 0,1 procent rækker
select * from my_test order by id offset 10 rows first 0.1 percent rows only;
– offset 10 rækker henter de første 3 rækker med bånd. Det betyder, at alle de øverste rækker med uafgjort også vil blive inkluderet i resultatet
select * from my_test order by name fetch first 3 rows with ties;
Hvis du tjekker optimeringsplanen for ovenstående forespørgsel, vil du opdage, at optimizer bruger rank()-funktionen som vist ovenfor i Pre 12c tilfælde
Begrænsning
(1)Hvis du har en SELECT-sætning med FOR UPDATE, kan du ikke bruge den.
(2)SELECT-sætningen kan ikke CURRVAL eller NEXTVAL af sekvenser
(3) Hvis forespørgslen til de materialiserede visninger har denne klausul, så kan du ikke foretage en trinvis opdatering af den materialiserede visning
Håber du kan lide artiklen om Top-N-forespørgsler i oracle og sideinddeling i oracle-forespørgsler. Giv venligst feedback
Læser også
Lead-funktion i Oracle
RANK-funktion i Oracle
https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljoffsetfetch.html