206 votes

Quelle est la différence entre les fonctions RANK () et DENSE_RANK () dans Oracle?

Quelle est la différence entre les fonctions RANK () et DENSE_RANK ()? .Comment trouver le nième salaire dans la table de vide et les données de table mentionnées également.

 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
 

Si, dans le tableau, les données ont des "nuls", que se passera-t-il pour connaître le nième salaire?

313voto

DCookie Points 22921

GRADE vous donne le classement au sein de votre ordre de partition. Les liens sont attribués au même rang, avec le prochain classement(s) sauté. Donc, si vous avez 3 éléments du rang 2, au rang suivant répertoriées sont classés en 5.

DENSE_RANK de nouveau vous donne le classement au sein de votre ordre de partition, mais les rangs sont consécutifs. Pas de rangs sont ignorées si il y a des rangs avec plusieurs éléments.

Comme pour les valeurs null, cela dépend de la clause ORDER BY. Voici un simple script de test, vous pouvez jouer avec pour voir ce qui se passe:

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.

Voici un lien pour une bonne explication et des exemples.

112voto

Lukas Eder Points 48046

Cet article explique bien. Essentiellement, vous pouvez le regarder comme tel:

CREATE TABLE t AS
SELECT 'a' v UNION ALL
SELECT 'a'   UNION ALL
SELECT 'a'   UNION ALL
SELECT 'b'   UNION ALL
SELECT 'c'   UNION ALL
SELECT 'c'   UNION ALL
SELECT 'd'   UNION ALL
SELECT 'e';

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;

Le ci-dessus donnera:

+---+------------+------+------------+
| 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 |
+---+------------+------+------------+

Dans les mots

  • ROW_NUMBER() attribue une valeur unique pour chaque ligne
  • RANK() attribue le même numéro de ligne de la même valeur, laisser de "trous"
  • DENSE_RANK() attribue le même numéro de ligne de la même valeur, sans laisser de "trous"

11voto

Anant_00 Points 21
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

6voto

sélectionnez empno, salaire, numéro_rille () sur (ordre par salaire décroissant), série (Rank) sur (ordre par salaire décroissant), grade, dense_rank () sur (ordre par traitement décroissant) comme denseRank de emp;

Row_number () -> Utilisé pour générer le numéro de série

Dense_rank donnera un rang continu mais le rang sera sauté en cas de conflit de rang.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X