Je me bats avec le mot clé distinct dans sql
. Je veux juste afficher tous les numéros de ligne de valeurs uniques (distinct
) dans une colonne et j'ai donc essayé:
SELECT distinct id, ROW_NUMBER() OVER (ORDER BY id) AS RowNum
FROM table
where fid = 64
cependant, le code ci-dessous me donne les valeurs distinct
:
SELECT distinct id FROM table where fid = 64
mais quand essayé avec Row_Number
.
alors cela ne fonctionne pas.
Utilisez ceci:
SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS RowNum FROM
(SELECT DISTINCT id FROM table WHERE fid = 64) Base
et mettre la "sortie" d'une requête comme "entrée" d'une autre.
Utilisation du CTE:
; WITH Base AS (
SELECT DISTINCT id FROM table WHERE fid = 64
)
SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS RowNum FROM Base
Les deux requêtes doivent être équivalentes.
Techniquement, vous pourriez
SELECT DISTINCT id, ROW_NUMBER() OVER (PARTITION BY id ORDER BY id) AS RowNum
FROM table
WHERE fid = 64
mais si vous augmentez le nombre de champs DISTINCT, vous devez mettre tous ces champs dans le PARTITION BY
, donc par exemple
SELECT DISTINCT id, description,
ROW_NUMBER() OVER (PARTITION BY id, description ORDER BY id) AS RowNum
FROM table
WHERE fid = 64
J'espère même que vous comprenez que vous allez à l'encontre des conventions de nommage standard ici, id
devrait probablement être une clé primaire, donc unique par définition, si bien qu'un DISTINCT
serait inutile, à moins que vous ne coupliez la requête avec quelque JOIN
s/UNION ALL
...
Cela peut être fait très simplement, vous étiez déjà assez proche
SELECT distinct id, DENSE_RANK() OVER (ORDER BY id) AS RowNum
FROM table
WHERE fid = 64
Cet article traite d'une relation intéressante entre ROW_NUMBER()
et DENSE_RANK()
(la fonction RANK()
n'est pas traitée spécifiquement). Lorsque vous avez besoin d'une ROW_NUMBER()
générée sur une instruction SELECT DISTINCT
, Le ROW_NUMBER()
) produira des valeurs distinctes avant ils sont supprimés par le mot clé DISTINCT
. 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 |
+---+------------+
Considérant que cette requête:
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 la clause ORDER BY
De la fonction DENSE_RANK()
aura besoin de toutes les autres colonnes de la clause SELECT DISTINCT
Pour fonctionner correctement.
Utilisation de la syntaxe standard PostgreSQL/Sybase/SQL (clause WINDOW
):
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
... tu auras:
+---+------------+------+------------+
| 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 |
+---+------------+------+------------+
L'utilisation de DISTINCT
provoque des problèmes lors de l'ajout de champs et peut également masquer des problèmes dans votre sélection. Utilisation GROUP BY
comme une alternative comme celle-ci:
SELECT id
,ROW_NUMBER() OVER (ORDER BY id) AS RowNum
FROM table
where fid = 64
group by id
Ensuite, vous pouvez ajouter d'autres informations intéressantes à partir de votre sélection, comme ceci:
,count(*) as thecount
ou
,max(description) as description
Que diriez-vous de quelque chose comme
;WITH DistinctVals AS (
SELECT distinct id
FROM table
where fid = 64
)
SELECT id,
ROW_NUMBER() OVER (ORDER BY id) AS RowNum
FROM DistinctVals
Tu pourrais aussi essayer
SELECT distinct id, DENSE_RANK() OVER (ORDER BY id) AS RowNum
FROM @mytable
where fid = 64
Essaye ça
SELECT distinct id
FROM (SELECT id, ROW_NUMBER() OVER (ORDER BY id) AS RowNum
FROM table
WHERE fid = 64) t
Ou utilisez RANK()
au lieu du numéro de ligne et sélectionnez les enregistrements DISTINCT rank
SELECT id
FROM (SELECT id, ROW_NUMBER() OVER (PARTITION BY id ORDER BY id) AS RowNum
FROM table
WHERE fid = 64) t
WHERE t.RowNum=1
Cela renvoie également les identifiants distincts
Essaye ça:
;WITH CTE AS (
SELECT DISTINCT id FROM table WHERE fid = 64
)
SELECT id, ROW_NUMBER() OVER (ORDER BY id) AS RowNum
FROM cte
WHERE fid = 64