Cet article traite d'une relation intéressante entre ROW_NUMBER()
et DENSE_RANK()
(le RANK()
n'est pas traitée spécifiquement). Lorsque vous avez besoin d'un ROW_NUMBER()
sur un SELECT DISTINCT
déclaration, le ROW_NUMBER()
produira des valeurs distinctes avant ils sont supprimés par le DISTINCT
mot-clé. Par exemple, cette requête
SELECT DISTINCT
v,
ROW_NUMBER() OVER (ORDER BY v) row_number
FROM t
ORDER BY v, row_number
... pourrait produire ce résultat ( DISTINCT
n'a aucun effet) :
+---+------------+
| V | ROW_NUMBER |
+---+------------+
| a | 1 |
| a | 2 |
| a | 3 |
| b | 4 |
| c | 5 |
| c | 6 |
| d | 7 |
| e | 8 |
+---+------------+
Alors que cette question :
SELECT DISTINCT
v,
DENSE_RANK() OVER (ORDER BY v) row_number
FROM t
ORDER BY v, row_number
... produit ce que vous voulez probablement dans ce cas :
+---+------------+
| V | ROW_NUMBER |
+---+------------+
| a | 1 |
| b | 2 |
| c | 3 |
| d | 4 |
| e | 5 |
+---+------------+
Notez que le ORDER BY
clause de la DENSE_RANK()
aura besoin de toutes les autres colonnes du SELECT DISTINCT
pour fonctionner correctement.
La raison en est que, logiquement, Les fonctions de fenêtre sont calculées avant DISTINCT
est appliqué .
Les trois fonctions en comparaison
Utilisation de la syntaxe standard PostgreSQL / Sybase / SQL ( WINDOW
clause) :
SELECT
v,
ROW_NUMBER() OVER (window) row_number,
RANK() OVER (window) rank,
DENSE_RANK() OVER (window) dense_rank
FROM t
WINDOW window AS (ORDER BY v)
ORDER BY v
... vous obtiendrez :
+---+------------+------+------------+
| 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 |
+---+------------+------+------------+