Wat is het verschil tussen de functies RANK() en DENSE_RANK() in oracle?

Wat is het verschil tussen de functies rank()en Dense_rank()? Hoe vind je het nde salaris in de volgende emptbltabel?

DEPTNO  EMPNAME    SAL
------------------------------
10       rrr    10000.00
11       nnn    20000.00
11       mmm    5000.00
12       kkk    30000.00
10       fff    40000.00
10       ddd    40000.00
10       bbb    50000.00
10       ccc    50000.00

Als in de tabelgegevens nullsstaan, wat gebeurt er dan als ik het nthsalaris wil weten?


Antwoord 1, autoriteit 100%

RANK geeft u de rangorde binnen uw bestelde partitie. Ties krijgen dezelfde rangorde, met de volgende rangschikking(en) overgeslagen. Dus als je 3 items op rang 2 hebt, is de volgende rangschikking rang 5.

DENSE_RANK geeft u opnieuw de rangorde binnen uw geordende partitie, maar de rangschikkingen zijn opeenvolgend. Er worden geen rangen overgeslagen als er rangen zijn met meerdere items.

Wat nulls betreft, dit hangt af van de ORDER BY-clausule. Hier is een eenvoudig testscript waarmee je kunt spelen om te zien wat er gebeurt:

with q as (
select 10 deptno, 'rrr' empname, 10000.00 sal from dual union all
select 11, 'nnn', 20000.00 from dual union all
select 11, 'mmm', 5000.00 from dual union all
select 12, 'kkk', 30000 from dual union all
select 10, 'fff', 40000 from dual union all
select 10, 'ddd', 40000 from dual union all
select 10, 'bbb', 50000 from dual union all
select 10, 'xxx', null from dual union all
select 10, 'ccc', 50000 from dual)
select empname, deptno, sal
     , rank() over (partition by deptno order by sal nulls first) r
     , dense_rank() over (partition by deptno order by sal nulls first) dr1
     , dense_rank() over (partition by deptno order by sal nulls last) dr2
 from q; 
EMP     DEPTNO        SAL          R        DR1        DR2
--- ---------- ---------- ---------- ---------- ----------
xxx         10                     1          1          4
rrr         10      10000          2          2          1
fff         10      40000          3          3          2
ddd         10      40000          3          3          2
ccc         10      50000          5          4          3
bbb         10      50000          5          4          3
mmm         11       5000          1          1          1
nnn         11      20000          2          2          2
kkk         12      30000          1          1          1
9 rows selected.

Hier is een linknaar een goede uitleg en enkele voorbeelden.


Antwoord 2, autoriteit 37%

Dit artikel hier legt het mooi uit.In wezen kun je het als volgt bekijken:

CREATE TABLE t AS
SELECT 'a' v FROM dual UNION ALL
SELECT 'a'   FROM dual UNION ALL
SELECT 'a'   FROM dual UNION ALL
SELECT 'b'   FROM dual UNION ALL
SELECT 'c'   FROM dual UNION ALL
SELECT 'c'   FROM dual UNION ALL
SELECT 'd'   FROM dual UNION ALL
SELECT 'e'   FROM dual;
SELECT
  v,
  ROW_NUMBER() OVER (ORDER BY v) row_number,
  RANK()       OVER (ORDER BY v) rank,
  DENSE_RANK() OVER (ORDER BY v) dense_rank
FROM t
ORDER BY v;

Het bovenstaande levert het volgende op:

+---+------------+------+------------+
| V | ROW_NUMBER | RANK | DENSE_RANK |
+---+------------+------+------------+
| a |          1 |    1 |          1 |
| a |          2 |    1 |          1 |
| a |          3 |    1 |          1 |
| b |          4 |    4 |          2 |
| c |          5 |    5 |          3 |
| c |          6 |    5 |          3 |
| d |          7 |    7 |          4 |
| e |          8 |    8 |          5 |
+---+------------+------+------------+

In woorden

  • row_number()kent een unieke waarde toe aan elke rij
  • rank()kent hetzelfde rijnummer toe aan dezelfde waarde, waardoor “gaten” overblijven
  • Dense_rank()kent hetzelfde rijnummer toe aan dezelfde waarde, zodat er geen “gaten” achterblijven

Antwoord 3, autoriteit 4%

rank(): het wordt gebruikt om een record binnen een groep rijen te rangschikken.

dense_rank(): De DENSE_RANK-functie werkt als de RANK-functie, behalve dat het opeenvolgende rangen toewijst.

Query –

select 
    ENAME,SAL,RANK() over (order by SAL) RANK
from 
    EMP;

Uitvoer –

+--------+------+------+
| ENAME  | SAL  | RANK |
+--------+------+------+
| SMITH  |  800 |    1 |
| JAMES  |  950 |    2 |
| ADAMS  | 1100 |    3 |
| MARTIN | 1250 |    4 |
| WARD   | 1250 |    4 |
| TURNER | 1500 |    6 |
+--------+------+------+

Query –

select 
    ENAME,SAL,dense_rank() over (order by SAL) DEN_RANK
from 
    EMP;

Uitvoer –

+--------+------+-----------+
| ENAME  | SAL  |  DEN_RANK |
+--------+------+-----------+
| SMITH  |  800 |         1 |
| JAMES  |  950 |         2 |
| ADAMS  | 1100 |         3 |
| MARTIN | 1250 |         4 |
| WARD   | 1250 |         4 |
| TURNER | 1500 |         5 |
+--------+------+-----------+

Antwoord 4, autoriteit 3%

SELECT empno,
       deptno,
       sal,
       RANK() OVER (PARTITION BY deptno ORDER BY sal) "rank"
FROM   emp;
     EMPNO     DEPTNO        SAL       rank
---------- ---------- ---------- ----------
      7934         10       1300          1
      7782         10       2450          2
      7839         10       5000          3
      7369         20        800          1
      7876         20       1100          2
      7566         20       2975          3
      7788         20       3000          4
      7902         20       3000          4
      7900         30        950          1
      7654         30       1250          2
      7521         30       1250          2
      7844         30       1500          4
      7499         30       1600          5
      7698         30       2850          6
SELECT empno,
       deptno,
       sal,
       DENSE_RANK() OVER (PARTITION BY deptno ORDER BY sal) "rank"
FROM   emp;
     EMPNO     DEPTNO        SAL       rank
---------- ---------- ---------- ----------
      7934         10       1300          1
      7782         10       2450          2
      7839         10       5000          3
      7369         20        800          1
      7876         20       1100          2
      7566         20       2975          3
      7788         20       3000          4
      7902         20       3000          4
      7900         30        950          1
      7654         30       1250          2
      7521         30       1250          2
      7844         30       1500          3
      7499         30       1600          4
      7698         30       2850          5

Antwoord 5

select empno
       ,salary
       ,row_number() over(order by salary desc) as Serial
       ,Rank() over(order by salary desc) as rank
       ,dense_rank() over(order by salary desc) as denseRank
from emp ;

row_number()-> Gebruikt voor het genereren van serienummer

Dense_rank()zal een continue rang geven, maar rank()zal rang overslaan in het geval van botsing van rang.


Antwoord 6

Het enige verschil tussen de functies RANK() en DENSE_RANK() is in gevallen waar er een “gelijkspel” is; d.w.z. in gevallen waarin meerdere waarden in een set dezelfde rangorde hebben. In dergelijke gevallen zal RANK() niet-opeenvolgende “rangen” toewijzen aan de waarden in de set (resulterend in hiaten tussen de gehele rangschikkingswaarden wanneer er een gelijkspel is), terwijl DENSE_RANK() opeenvolgende rangschikkingen toekent aan de waarden in de ingesteld (zodat er geen hiaten zijn tussen de gehele rangschikkingswaarden in het geval van een gelijkspel).

Beschouw bijvoorbeeld de set {25, 25, 50, 75, 75, 100}. Voor een dergelijke set geeft RANK() {1, 1, 3, 4, 4, 6} terug (merk op dat de waarden 2 en 5 worden overgeslagen), terwijl DENSE_RANK() {1,1,2,3, 3,4}.


Antwoord 7

Rank() SQL-functie genereert rangorde van de gegevens binnen een geordende reeks waarden, maar de volgende rangorde na de vorige rangorde is rijnummer van die specifieke rij. Aan de andere kant genereert de Dense_Rank() SQL-functie het volgende nummer in plaats van rijnummer te genereren. Hieronder staat het SQL-voorbeeld dat het concept zal verduidelijken:

Select ROW_NUMBER() over (order by Salary) as RowNum, Salary, 
RANK() over (order by Salary) as Rnk, 
DENSE_RANK() over (order by Salary) as DenseRnk from (
Select 1000 as Salary union all
Select 1000 as Salary union all
Select 1000 as Salary union all
Select 2000 as Salary union all
Select 3000 as Salary union all
Select 3000 as Salary union all
Select 8000 as Salary union all
Select 9000 as Salary) A

Het genereert de volgende uitvoer:

----------------------------
RowNum  Salary  Rnk DenseRnk
----------------------------
1       1000    1   1
2       1000    1   1
3       1000    1   1
4       2000    4   2
5       3000    5   3
6       3000    5   3
7       8000    7   4
8       9000    8   5

Antwoord 8

Rang en dichte rang geeft de rang in de gepartitioneerde dataset.

Rank() : Het geeft je geen opeenvolgende gehele getallen.

Dense_rank() : Het geeft je opeenvolgende gehele getallen.

voer hier de afbeeldingsbeschrijving in

In bovenstaande afbeelding is de rangorde van 10008 zip 2 door de functie density_rank() en 24 door de functie rang() aangezien het het rijnummer beschouwt.


Antwoord 9

Rank(), Dense_rank(), row_number()
Dit zijn allemaal vensterfuncties, wat betekent dat ze in eerste instantie als venster fungeren boven een geordende invoerset. Aan deze vensters is afhankelijk van de behoefte een andere functionaliteit gekoppeld. Hier is de bovenstaande 3:

row_number()

Begin met row_number()omdat dit de basis vormt van deze gerelateerde vensterfuncties. row_number()zoals de naam suggereert geeft een uniek nummer aan de reeks rijen waarop het is toegepast. Vergelijkbaar met het geven van een serienummer aan elke rij.

rank()

Een subversie van row_number()kan worden gezegd als rank(). Rank() wordt gebruikt om hetzelfde serienummer te geven aan die geordende setrijen die duplicaten zijn, maar het houdt de telling nog steeds als vergelijkbaar met een row_number()voor al diegenen na duplicaten rank() wat betekent vanaf hieronder bijv. Voor gegevens 2 row_number() =rank(), wat betekent dat beide gewoon verschillen in de vorm van duplicaten.

Data row_number() rank() dense_rank() 
    1         1                    1       1
    1         2                    1       1
    1         3                    1       1
    2         4                    4       2

Eindelijk,

Dense_rank() is een uitgebreide versie van rank() zoals de naam doet vermoeden is het compact omdat, zoals je kunt zien in het bovenstaande voorbeeld rank() = dichte_rank() voor alle data 1, maar alleen dat voor data 2 het verschilt in de vorm dat het de volgorde van rang() van vorige rang() handhaaft, niet de feitelijke gegevens


Antwoord 10

Het enige verschil tussen de functies RANK() en DENSE_RANK() is in gevallen waar er een “gelijkspel” is; d.w.z. in gevallen waarin meerdere waarden in een set dezelfde rangorde hebben. In dergelijke gevallen zal RANK() niet-opeenvolgende “rangen” toewijzen aan de waarden in de set (resulterend in hiaten tussen de gehele rangschikkingswaarden wanneer er een gelijkspel is), terwijl DENSE_RANK() opeenvolgende rangschikkingen toekent aan de waarden in de ingesteld (zodat er geen hiaten zijn tussen de gehele rangschikkingswaarden in het geval van een gelijkspel).

Beschouw bijvoorbeeld de set {30, 30, 50, 75, 75, 100}. Voor een dergelijke set geeft RANK() {1, 1, 3, 4, 4, 6} terug (merk op dat de waarden 2 en 5 worden overgeslagen), terwijl DENSE_RANK() {1,1,2,3, 3,4}.

Other episodes