web-dev-qa-db-fra.com

Fonction de fenêtre PostgreSQL: row_number () over (partition col order by col2)

L'ensemble de résultats suivant est dérivé d'une requête SQL avec quelques jointures et une union. La requête SQL regroupe déjà des lignes sur Date et jeu. J'ai besoin d'une colonne pour décrire le nombre de tentatives d'un jeu partitionné par date.

Username   Game     ID   Date

johndoe1   Game_1   100  7/22/14 1:52 AM
johndoe1   Game_1   100  7/22/14 1:52 AM
johndoe1   Game_1   100  7/22/14 1:52 AM
johndoe1   Game_1   100  7/22/14 1:52 AM
johndoe1   Game_1   121  7/22/14 1:56 AM
johndoe1   Game_1   121  7/22/14 1:56 AM
johndoe1   Game_1   121  7/22/14 1:56 AM
johndoe1   Game_1   121  7/22/14 1:56 AM
johndoe1   Game_1   121  7/22/14 1:56 AM
johndoe1   Game_1   130  7/22/14 1:59 AM
johndoe1   Game_1   130  7/22/14 1:59 AM
johndoe1   Game_1   130  7/22/14 1:59 AM
johndoe1   Game_1   130  7/22/14 1:59 AM
johndoe1   Game_1   130  7/22/14 1:59 AM
johndoe1   Game_1   200  7/22/14 2:54 AM
johndoe1   Game_1   200  7/22/14 2:54 AM
johndoe1   Game_1   200  7/22/14 2:54 AM
johndoe1   Game_1   200  7/22/14 2:54 AM
johndoe1   Game_1   210  7/22/14 3:54 AM
johndoe1   Game_1   210  7/22/14 3:54 AM
johndoe1   Game_1   210  7/22/14 3:54 AM
johndoe1   Game_1   210  7/22/14 3:54 AM

J'ai la requête SQL suivante qui énumère les lignes de la partition mais pas entièrement correcte car je veux le nombre d'instances de ce jeu en fonction de la date et du jeu. Dans ce cas, johndoe1 a tenté à Game_1 cinq fois partitionné par les horodatages.

Cette requête renvoie l'ensemble de résultats ci-dessous

select *
, row_number() over (partition by ct."date" order by ct."date") as "Attempts"
from csv_temp as ct

Username   Game     ID   Date             Attempts  (Desired Attempts col.)

johndoe1   Game_1   100  7/22/14 1:52 AM  1          1
johndoe1   Game_1   100  7/22/14 1:52 AM  2          1
johndoe1   Game_1   100  7/22/14 1:52 AM  3          1
johndoe1   Game_1   100  7/22/14 1:52 AM  4          1
johndoe1   Game_1   121  7/22/14 1:56 AM  1          2
johndoe1   Game_1   121  7/22/14 1:56 AM  2          2
johndoe1   Game_1   121  7/22/14 1:56 AM  3          2
johndoe1   Game_1   121  7/22/14 1:56 AM  4          2
johndoe1   Game_1   121  7/22/14 1:56 AM  5          2
johndoe1   Game_1   130  7/22/14 1:59 AM  1          3   
johndoe1   Game_1   130  7/22/14 1:59 AM  2          3
johndoe1   Game_1   130  7/22/14 1:59 AM  3          3
johndoe1   Game_1   130  7/22/14 1:59 AM  4          3
johndoe1   Game_1   130  7/22/14 1:59 AM  5          3
johndoe1   Game_1   200  7/22/14 2:54 AM  1          4
johndoe1   Game_1   200  7/22/14 2:54 AM  2          4
johndoe1   Game_1   200  7/22/14 2:54 AM  3          4
johndoe1   Game_1   200  7/22/14 2:54 AM  4          4
johndoe1   Game_1   210  7/22/14 3:54 AM  1          5
johndoe1   Game_1   210  7/22/14 3:54 AM  2          5
johndoe1   Game_1   210  7/22/14 3:54 AM  3          5
johndoe1   Game_1   210  7/22/14 3:54 AM  4          5

Tout pointeur serait d'une grande aide.

9
user1951677

Considérez que partition by Est similaire aux champs que vous utiliseriez group by, Puis, lorsque les valeurs de partition changent, la fonction de fenêtrage redémarre à 1

EDIT comme indiqué par a_horse_with_no_name, pour ce besoin, nous avons besoin de dense_rank() contrairement à row_number()rank() ou dense_rank() répétez les numéros qu'il attribue. row_number() doit être une valeur différente pour chaque ligne d'une partition. La différence entre rank() et dense_rank() est que ce dernier ne "saute" pas les nombres.

Pour votre requête, essayez:

dense_rank() over (partition by Username, Game order by ct."date") as "Attempts"

Soit dit en passant, vous ne partitionnez pas et ne triez pas par le même champ; une simple commande par serait suffisante si tel était le besoin. Ce n'est pas ici.

24
Used_By_Already