Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

Oracle में RANK, DENSE_RANK और ROW_NUMBER कार्य करता है

ओरेकल एनालिटिक फ़ंक्शंस विंडो नामक पंक्तियों के समूह के आधार पर एक समग्र मूल्य की गणना करता है जो वर्तमान पंक्ति के लिए गणना करने के लिए उपयोग की जाने वाली पंक्तियों की सीमा निर्धारित करता है। निम्नलिखित सबसे अधिक उपयोग किए जाने वाले विश्लेषणात्मक कार्य हैं।
– RANK, DENSE_RANK और ROW_NUMBER
– LAG और LEAD
– FIRST_VALUE और LAST_VALUE

मैं RANK, DENSE_RANK और ROW_NUMBER विश्लेषिकी कार्यों के बारे में चर्चा करूंगा। वे प्रकृति में काफी समान हैं और हमें आवश्यकता के आधार पर उपयोग करने की आवश्यकता है। मैं उनके बीच के अंतर को भी समझाऊंगा

यहाँ सामान्य वाक्य रचना है

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

Oracle में ROW_NUMBER फ़ंक्शन

ROW_NUMBER order_by_clause द्वारा निर्दिष्ट पंक्तियों के क्रमबद्ध क्रम में एक ही विंडो की प्रत्येक पंक्ति के लिए एक अद्वितीय संख्या निर्दिष्ट करता है।

आइए पहले नमूना डेटा बनाएं

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),
"DEPTNO" NUMBER(2,0),
CONSTRAINT "PK_EMP" PRIMARY KEY ("EMPNO"),
CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO")
REFERENCES "DEPT" ("DEPTNO") ENABLE
);

SQL> desc emp
Name Null? Type
---- ---- -----
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)

SQL> desc dept
Name Null? Type
---- ----- ----
DEPTNO NOT NULL NUMBER(2)
DNAME VARCHAR2(14)
LOC VARCHAR2(13)


insert into DEPT values(10, 'ACCOUNTING', 'NEW YORK');
insert into 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-yyyy'), 30000, null, 20 );
insert into emp values( 7902, 'Bill', 'ANALYST', 7832, to_date('9-6-2012','dd-mm-yyyy'), 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-yyyy'), 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?    Type
 ----------------------------------------- -------- ----------------------------
 EMPNO                                     NOT NULL NUMBER(4)
 ENAME                                              VARCHAR2(10)
 JOB                                                VARCHAR2(9)
 MGR                                                NUMBER(4)
 HIREDATE                                           DATE
 SAL                                                NUMBER(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          3

SQL> select
deptno, ename, sal,
 row_number() over (partition by deptno order by sal) "row_number"
from
emp;

DEPTNO        ENAME       SAL    row_number
---------- ---------- ---------- ---------- 
10          CLARK          0        1 
10          MILLER         0        2
10          allen          28573    3
20          SMITH          8000     1
20          ADAMS          11000    2
20          SCOTT          30000    3
20          FORD           30000    4
30          JAMES          9500     1
30          MARTIN         12500    2
30          WARD           12500    3
30          TURNER         15000    4
30          ALLEN          16000    5
30          BLAKE          28500    6 

13 rows selected.

Oracle में रैंक फ़ंक्शन

रैंक लगभग ROW_NUMBER के समान है, लेकिन समान मान वाली पंक्तियाँ, एक ही विंडो में, जिसके लिए खंड द्वारा निर्दिष्ट क्रम समान रैंक प्राप्त करता है, लेकिन अगली पंक्ति इसके अनुसार ROW_NUMBER प्राप्त करती है।

SQL> select
deptno, ename, sal,
 rank() over (partition by deptno order by sal) "RANK"
from
emp;

DEPTNO        ENAME       SAL    RANK
---------- ---------- ---------- ---------- 
10          CLARK          0        1 
10          MILLER         0        2
10          allen          28573    3
20          SMITH          8000     1
20          ADAMS          11000    2
20          SCOTT          30000    3
20          FORD           30000    3
30          JAMES          9500     1
30          MARTIN         12500    2
30          WARD           12500    2
30          TURNER         15000    4
30          ALLEN          16000    5
30          BLAKE          28500    6 

13 rows selected.

Oracle में Dense_rank फ़ंक्शन

DENSE_RANK लगभग रैंक के समान है, लेकिन यदि एक या अधिक मान समान हैं तो यह पंक्तियों के बीच अंतर नहीं छोड़ता है। जैसे निम्न उदाहरण में TURNER उसी समूह में WARD के बगल में DENSE_RANK 3 प्राप्त करता है।

SQL> select
deptno, ename, sal,
 dense_rank() over (partition by deptno order by sal) "DENSE_RANK"
from
emp;

DEPTNO        ENAME       SAL    DENSE_RANK
---------- ---------- ---------- ---------- 
10          CLARK          0        1 
10          MILLER         0        2
10          allen          28573    3
20          SMITH          8000     1
20          ADAMS          11000    2
20          SCOTT          30000    3
20          FORD           30000    3
30          JAMES          9500     1
30          MARTIN         12500    2
30          WARD           12500    2
30          TURNER         15000    3
30          ALLEN          16000    4
30          BLAKE          28500    5 

13 rows selected.

हम तीनों को एक ही प्रश्न में भी डाल सकते हैं

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 order by sal) "dense_rank"
        from
          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          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          5

13 rows selected.

हम डुप्लिकेट पंक्तियों को हटाने में Row_number और RANK फ़ंक्शन का उपयोग कर सकते हैं

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);

ये फ़ंक्शन टॉप-एन और बॉटम-एन क्वेरी के लिए बहुत उपयोगी हैं।

प्रत्येक विभाग में शीर्ष वेतन खोजने के लिए नीचे दिए गए SQL का उपयोग किया जा सकता है

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

आशा है कि आपको Oracle विश्लेषणात्मक कार्यों की तरह RANK, DENSE_RANK और ROW_NUMBER पर स्पष्टीकरण पसंद आया होगा और हम डेटा का विश्लेषण करने के लिए क्वेरी में कैसे उपयोग कर सकते हैं। प्रश्नों में इन कार्यों का उपयोग करते समय हमें बहुत सावधान रहना होगा अन्यथा परिणाम अलग होगा।

संबंधित लेख

Oracle में LEAD फ़ंक्शन
Oracle में विश्लेषणात्मक कार्य
Oracle साक्षात्कार प्रश्न
Oracle सेट ऑपरेटर
Oracle Sql ट्यूटोरियल
घने रैंक oracle प्रलेखन


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle एकाधिक मानों से मेल खाने वाली पंक्तियों को हटाएं

  2. Oracle RAC में इनमेमोरी डुप्लीकेट कन्फ्यूजन

  3. क्या किसी को पता है कि क्रेडेंशियल जारी रखने के लिए जेडी डेवलपर/एसक्यूएल डेवलपर किस एन्क्रिप्टिंग तकनीक का उपयोग कर रहा है?

  4. किसी कनेक्टेड उपयोगकर्ता को Oracle 10g डेटाबेस स्कीमा से हटाना

  5. NEW_TIME () Oracle में फ़ंक्शन