sql >> Database teknologi >  >> RDS >> Oracle

RANK, DENSE_RANK og ROW_NUMBER funktioner i Oracle

Oracle Analytic-funktioner beregner en aggregeret værdi baseret på en gruppe rækker kaldet vindue, som bestemmer rækkevidden af ​​rækker, der bruges til at udføre beregningerne for den aktuelle række. Følgende er de mest brugte analytiske funktioner.
– RANK, DENSE_RANK og ROW_NUMBER
– LAG og LEAD
– FIRST_VALUE og LAST_VALUE

Jeg vil diskutere RANK-, DENSE_RANK- og ROW_NUMBER-analysefunktioner. De ligner hinanden meget, og vi skal bruge dem på grundlag af kravet. Jeg vil også forklare forskellen mellem dem

Her er den generelle syntaks

analytic_function([ arguments ]) OVER ([ query_partition_clause ] [ order_by_clause  ])

ROW_NUMBER funktion i Oracle

ROW_NUMBER tildeler et unikt nummer til hver række i samme vindue i den ordnede rækkefølge af rækker, der er angivet af order_by_clause.

Lad os først oprette eksempeldata

OPRET TABEL "DEPT"( "DEPTNO" NUMMER(2,0),"DNAME" VARCHAR2(14),"LOC" VARCHAR2(13),BEGRÆNSNING "PK_DEPT" PRIMÆR NØGLE ("DEPTNO"))OPRET TABEL " EMP"( "EMPNO" NUMMER(4,0),"ENAME" VARCHAR2(10),"JOB" VARCHAR2(9),"MGR" NUMMER(4,0),"UDLEJNING" DATO,"SAL" NUMMER(7 ,2),"KOMM" NUMMER(7,2),"DEPTNO" NUMMER(2,0),BEGRÆNSNING "PK_EMP" PRIMÆR NØGLE ("EMPNO"), CONSTRAINT "FK_DEPTNO" UDENLANDSKE NØGLE ("DEPTNO")REFERENCER "DEPT " ("DEPTNO") ENABLE);SQL> desc empName Null? Type---- ---- -----EMPNO IKKE NULL NUMMER(4)ENAME VARCHAR2(10)JOB VARCHAR2(9)MGR NUMMER(4)UDLEJNING DATO NUMMER(7,2)KOMM NUMMER(7,2) )DEPTNO NUMMER(2)SQL> desc deptName Null? Indtast---- ----- ----DEPTNO NOT NULL NUMMER(2)DNAME VARCHAR2(14)LOC VARCHAR2(13)indsæt i DEPT-værdier(10, 'REGNSKAB', 'NEW YORK');indsæt i dept values(20, 'RESEARCH', 'DALLAS');insert into dept values(30, 'RESEARCH', 'DELHI');insert into dept values(40, 'RESEARCH', 'MUMBAI');commit;insert into emp values( 7839, 'Clark', 'MANAGER', 7839, to_date('9-6-2008','dd-mm-yyyy'), 28573, null, 10 );insert into emp values( 7782, 'Clara ', 'MANAGER', 7839, to_date('9-6-2008','dd-mm-yyyy'), 0, null, 10 );insert into emp values( 7934, 'Blake', 'MANAGER', 7839 , to_date('1-5-2007','dd-mm-yyyy'), 0, null, 10 );insert into emp values( 7788, 'Scott', 'ANALYST', 7788, to_date('9-6 -2012','dd-mm-åååå'), 30000, null, 20 );insert into emp values( 7902, 'Bill', 'ANALYST', 7832, to_date('9-6-2012','dd- mm-åååå'), 30000, null, 20 );insert into emp values( 7876, 'TPM', 'ANALYST', 7566, to_date('9-6-2017','dd-mm-yyyy'), 11000 , null, 20 );insert into emp values( 7369, 'TPM1', 'ANALYST', 7566, to_date('9-6-2017',' dd-mm-åååå'), 8000, null, 20 );insert into emp values( 7698, 'A1', 'ANALYST', 7788, to_date('9-6-2017','dd-mm-yyyy') , 28500, null, 30 );insert into emp values( 7499, 'A2', 'ANALYST', 7698, to_date('9-7-2017','dd-mm-yyyy'), 16000, null, 30 );insert into emp values( 7844, 'A3', 'ANALYST', 7698, to_date('9-7-2017','dd-mm-yyyy'), 15000, null, 30 );insert into emp values( 7654 , 'A4', 'ANALYST', 7698, to_date('9-7-2017','dd-mm-yyyy'), 12500, null, 30 );insert into emp values( 7521, 'A5', 'ANALYST ', 7698, to_date('9-7-2017','dd-mm-yyyy'), 12500, null, 30 );insert into emp values( 7900, 'A6', 'ANALYST', 77698, to_date(' 9-7-2017','dd-mm-yyyy'), 0, null, 30 );commit;
SQL> desc emp Name Null? Skriv -------------------------------------------------- ---------------------------- EMPNO IKKE NULL NUMMER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMMER(4) UDLEJSDATO SALGNUMMER(7,2) KOMM.NUMMER(7,2) DEPTNO NUMMER(2)SQL> vælg deptno ,count(*) fra emp group by deptno; DEPTNO COUNT(*)---------- ---------- 30 6 20 4 10 3SQL> selectdeptno, ename, sal, row_number() over (partition efter deptno rækkefølge efter sal) "row_number"fromemp;DEPTNO ENAME SAL række_nummer--------- ---------- ---------- ---------- 10 CLARK 0 1 10 MILLER 0 210 ALLEN 28573 320 SMITH 8000 120 ADAMS 11000 220 SCOTT 30000 320 FORD 30000 430 JAMES 9500 130 MARTIN 12500 230 WARD 12500 330 TURNER 15000 430 ALLEN 16000 530 BLAKE 28500 6 13 ROWS VÆLGT. 

RANK-funktion i Oracle

RANK er næsten den samme som ROW_NUMBER, men rækker med lige værdier, med i samme vindue, hvor der er angivet rækkefølge efter klausul, modtager samme rang, men næste række modtager RANK i henhold til ROW_NUMBER.

SQL> selectdeptno, ename, sal, rank() over (partition efter deptno rækkefølge efter sal) "RANK"fromemp;DEPTNO ENAME SAL RANK------------ -- ---------- ---------- 10 CLARK 0 1 10 MILLER 0 210 allen 28573 320 SMITH 8000 120 ADAMS 11000 220 SCOTT 30000 320 FORD 30000 330 JAMES 120000IN 230 WARD 12500 230 TURNER 15000 430 ALLEN 16000 530 BLAKE 28500 6 13 rækker valgt.

Dense_rank-funktion i Oracle

DENSE_RANK er næsten den samme som RANK, men den efterlader ikke mellemrum mellem rækkerne, hvis en eller flere værdier er ens. Som i følgende eksempel modtager TURNER ved siden af ​​WARD i samme gruppe DENSE_RANK 3.

SQL> selectdeptno, ename, sal, dense_rank() over (partition efter deptno rækkefølge efter sal) "DENSE_RANK"fromemp;DEPTNO ENAME SAL DENSE_RANK---------- -------- -- ---------- ---------- 10 CLARK 0 1 10 MILLER 0 210 allen 28573 320 SMITH 8000 120 ADAMS 11000 220 SCOTT 30000 320 FORD 30000 330 JAMES 120000IN 230 WARD 12500 230 TURNER 15000 330 ALLEN 16000 430 BLAKE 28500 5 13 rækker valgt.

Vi kan også sætte alle tre i den enkelte forespørgsel

vælg deptno, ename, sal, row_number() over (partition efter deptno rækkefølge efter sal) "row_number", rank() over (partition efter deptno rækkefølge efter sal) "rank", dense_rank() over (partition efter deptno rækkefølge efter sal) "dense_rank" fra emp; DEPTNO ENAME SAL row_number rank dense_rank--------- ---------- ---------- ---------- ---- ------ ---------- 10 CLARK 0 1 1 1 10 MILLER 0 2 1 1 10 allen 28573 3 3 2 20 SMITH 8000 1 1 1 20 ADAMS 11000 2 2 2 20 SCOTT 30000 3 3 20 FORD 30000 4 3 3 30 JAMES 9500 1 1 1 30 MARTIN 12500 2 2 2 30 WARD 12500 3 2 2 30 TURNER 15000 4 4 3 6 30 4 3 6 30 40 30 50 ALLEN 60 5 5 6 5 5 0 5 5 6 5 6 5 6 5 6 0 3 0 5 0 5 6 5 valgt.> 

Vi kan bruge Row_number og RANK-funktionen til at slette de duplikerende rækker

slet fra t hvor rowid IN (vælg fri fra (vælg rowid fri, rækkenummer() over (partition efter kolonnenavn rækkefølge efter rowid) rn fra t) hvor rn <> 1);

Disse funktioner er meget nyttige til  for top-N og bottom-N-forespørgsler.

Nedenstående SQL kan bruges til at finde toplønnen i hver afdeling

SQL> vælg * (selectdeptno, ename, sal, row_number() over (partition efter deptno rækkefølge efter sal) "row_number"fromemp ) hvor row_number=1;

Håber du kan lide forklaring på RANK, DENSE_RANK og ROW_NUMBER som Oracle Analytic-funktioner og hvordan vi kan bruges i forespørgslen til at analysere dataene. Vi skal være meget forsigtige, når vi bruger disse funktioner i forespørgslerne, ellers ville resultatet blive anderledes.

Relaterede artikler

LEAD-funktion i Oracle
Analytiske funktioner i Oracle
Oracle-interviewspørgsmål
Oracle Set Operators
Oracle Sql-vejledning
Oracle-dokumentation med tæt rangering


  1. Top 5 gratis værktøjer til databasedesign

  2. Når et script udføres på SQLPlus, udskriver det en sekvens af tal i stedet for output

  3. Hvordan man erklærer og viser en variabel i Oracle

  4. Typecast streng til heltal