Oracle
 sql >> Datenbank >  >> RDS >> Oracle

RANK-, DENSE_RANK- und ROW_NUMBER-Funktionen in Oracle

Oracle Analytic-Funktionen berechnen einen aggregierten Wert basierend auf einer Gruppe von Zeilen namens Fenster, die den Zeilenbereich bestimmen, der zum Ausführen der Berechnungen für die aktuelle Zeile verwendet wird. Im Folgenden sind die am häufigsten verwendeten Analysefunktionen aufgeführt.
– RANK, DENSE_RANK und ROW_NUMBER
– LAG und LEAD
– FIRST_VALUE und LAST_VALUE

Ich würde über die Analysefunktionen RANK, DENSE_RANK und ROW_NUMBER sprechen. Sie sind ihrer Art nach ziemlich ähnlich und wir müssen sie je nach Anforderung verwenden. Ich würde auch den Unterschied zwischen ihnen erklären

Hier ist die allgemeine Syntax

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

ROW_NUMBER-Funktion in Oracle

ROW_NUMBER weist jeder Zeile desselben Fensters in der durch order_by_clause.

angegebenen geordneten Folge von Zeilen eine eindeutige Nummer zu

Lassen Sie uns zuerst Beispieldaten erstellen

CREATE TABLE "DEPT"( "DEPTNO" NUMBER(2,0),"DNAME" VARCHAR2(14),"LOC" VARCHAR2(13),CONSTRAINT "PK_DEPT" PRIMARY KEY ("DEPTNO"))CREATE TABLE " EMP"( "EMPNO" NUMBER(4,0),"ENAME" VARCHAR2(10),"JOB" VARCHAR2(9),"MGR" NUMBER(4,0),"HIREDATE" DATE,"SAL" NUMBER(7 ,2),"COMM" NUMBER(7,2),"ABTEILNR" NUMMER(2,0),CONSTRAINT "PK_EMP" PRIMARY KEY ("EMPNO"),CONSTRAINT "FK_ABTEILNR" FOREIGN KEY ("ABTN")REFERENCES "ABTEIL " ("DEPTNO") ENABLE);SQL> desc empName Null? Typ---- ---- -----EMPNO NOT NULL NUMBER(4)ENAME VARCHAR2(10)JOB VARCHAR2(9)MGR NUMMER(4)EINSTELLDATEN NUMMER(7,2)COMM NUMBER(7,2 )DEPTNO NUMBER(2)SQL> desc deptName Null? Typ---- ----- ----DEPTNO NOT NULL NUMBER(2)DNAME VARCHAR2(14)LOC VARCHAR2(13)insert in DEPT values(10, 'ACCOUNTING', 'NEW YORK');insert into dept values(20, 'RESEARCH', 'DALLAS');insert in dept values(30, 'RESEARCH', 'DELHI');insert in 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 ); einfügen in 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-yyyy'), 30000, null, 20 );insert in emp values( 7902, 'Bill', 'ANALYST', 7832, to_date('9-6-2012','dd- mm-jjjj'), 30000, null, 20 );insert in 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-yyyy'), 8000, null, 20 );insert in 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 in emp values( 7844, 'A3', 'ANALYST', 7698, to_date('9-7-2017','dd-mm-yyyy'), 15000, null, 30 );insert in 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? Typ ----------------------------------------- -------- ---------------------------- EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) EINSTELLDATUM SAL NUMMER(7,2) COMM NUMBER(7,2) DEPTNO NUMBER(2)SQL> select deptno ,count(*) from emp group by deptno; DEPTNO COUNT(*)---------- ---------- 30 6 20 4 10 3SQL> selectdeptno, ename, sal, row_number() over (partition by deptno order by sal) "row_number"fromemp;DEPTNO ENAME SAL row_number---------- ---------- ---------- ---------- 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 ausgewählt. 

RANK-Funktion in Oracle

RANG ist fast identisch mit ROW_NUMBER, aber Zeilen mit gleichen Werten, mit im selben Fenster, für die die order by-Klausel angegeben ist, erhalten denselben Rang, aber die nächste Zeile erhält RANK gemäß ROW_NUMBER.

SQL> selectdeptno, ename, sal, rank() over (partition by deptno order by 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 9500 130 MARTIN 12500 230 WARD 12500 230 TURNER 15000 430 ALLEN 16000 530 BLAKE 28500 6 13 Reihen ausgewählt.

Dense_rank-Funktion in Oracle

DENSE_RANK ist fast derselbe wie der RANK, hinterlässt jedoch keine Lücke zwischen den Zeilen, wenn ein oder mehrere Werte gleich sind. Wie im folgenden Beispiel erhält TURNER neben WARD in derselben Gruppe DENSE_RANK 3.

SQL> selectdeptno, ename, sal, dense_rank() over (partition by deptno order by 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 9500 130 MARTIN 12500 230 WARD 12500 230 TURNER 15000 330 ALLEN 16000 430 BLAKE 28500 5 13 Reihen ausgewählt.

Wir können alle drei auch in einer einzigen Abfrage unterbringen

select deptno, ename, sal, row_number() over (partition by deptno order by sal) "row_number", rank() over (partition by deptno order by sal) "rank", dense_rank() over (partition by deptno Bestellung bei sal) "dense_rank" von emp; DEPTNO ENAME SAL Zeilennummer Rang Dichte_Rang---------- ---------- ---------- ---------- ---- ------ ---------- 10 CLARK 0 1 1 1 10 MILLER 0 2 1 1 10 Inbus 28573 3 3 2 20 SMITH 8000 1 1 1 20 ADAMS 11000 2 2 2 20 SCOTT 30000 3 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 30 ALLEN 16000 5 5 4 30 BLAKE 28500 6 6 513 Reihen selektiert> 

Wir können die Funktion Row_number und RANK verwenden, um die doppelten Zeilen zu löschen

delete from t where rowid IN ( select rid from (select rowid rid, row_number() over (partition by column_name order by rowid) rn from t) where rn <> 1);

Diese Funktionen sind sehr nützlich für Top-N- und Bottom-N-Abfragen.

Die folgende SQL kann verwendet werden, um das höchste Gehalt in jeder Abteilung zu finden

SQL> select * (selectdeptno, ename, sal, row_number() over (partition by deptno order by sal) "row_number"fromemp ) where row_number=1;

Ich hoffe, Sie mögen die Erklärung zu RANK, DENSE_RANK und ROW_NUMBER wie Oracle Analytic-Funktionen und wie wir in der Abfrage zur Analyse der Daten verwendet werden können. Wir müssen bei der Verwendung dieser Funktionen in den Abfragen sehr vorsichtig sein, sonst wäre das Ergebnis anders.

Verwandte Artikel

LEAD-Funktion in Oracle
Analytische Funktionen in Oracle
Oracle-Interviewfragen
Oracle-Set-Operatoren
Oracle-Sql-Tutorial
Dense-Rank-Orakel-Dokumentation