2010-05-19 8 views
1

Si vous avez l'instruction select ci-dessous où la PK est la clé primaire:SQL: sans un curseur, comment sélectionner des enregistrements en faisant un id entier unique (identité similaire) pour des dups?

select distinct dbo.DateAsInt(dateEntered) * 100 as PK, 
       recordDescription as Data 
from MyTable 

et la sortie est quelque chose comme ceci (les premiers chiffres sont espacés pour plus de clarté):

 PK    Data 
2010 01 01 00 New Years Day 
2010 01 01 00 Make Resolutions 
2010 01 01 00 Return Gifts 
2010 02 14 00 Valentines day 
2010 02 14 00 Buy flowers 

et vous voulez afficher quelque chose comme ceci:

 PK    Data 
2010 01 01 01 New Years Day 
2010 01 01 02 Make Resolutions 
2010 01 01 03 Return Gifts 
2010 02 14 01 Valentines day 
2010 02 14 02 Buy flowers 

est-il possible de faire le « 00 » dans le PK ont un effet de nombre « d'identité » dans un seul sel ect? Sinon, comment pouvez-vous incrémenter le nombre de 1 pour chaque activité trouvée pour cette date?

Je pense déjà en tapant pour essayer quelque chose comme Sum (cas quand ?? puis 1 fin) avec un groupe par.

Edit: (réponse fournie par JohnFX ci-dessous)

Ce fut la réponse finale:

select PK + row_number() over 
      (PARTITION BY eventid order by eventname) as PK, 
      recordDescription 
from  (select distinct -- Removes row counts of excluded rows) 
        dbo.DateAsInt(dateEntered) as PK, 
        recordDescription as Data 
      from  MyTable) A 
order by eventid, recordDescription 

Répondre

3

Je pense que vous cherchez ROW_NUMBER et la clause PARTITION associée.

SELECT DISTINCT dbo.DateAsInt(DateEntered) * 100 as PK, 
       ROW_NUMBER() OVER (PARTITION BY DateEntered ORDER BY recordDescription) as rowID, 
       recordDescription as Data 
FROM MyTable 

Si DateEntered a des valeurs en double vous voulez probablement aussi de vérifier DENSE_RANK() et RANK() en fonction de vos besoins spécifiques pour ce qu'il faut faire avec l'incrémenteur dans ces cas.

+0

Ceci a un grand potentiel de succès. Jusqu'à présent, je reçois un nombre distinct pour chaque date, mais j'essaie toujours de les obtenir à chaque début à 1 et incrémenter de un. (Je reçois des valeurs comme 5,7,15,2). Je lis sur les options que je tape. Réponse très prometteuse. Merci. –

+0

Certainement une bonne réponse. J'ai dû déplacer le distinct à une sous-requête, puis utiliser row_number sur la partition sur le résultat. Travaillé parfaitement. Le row_number comptait les lignes avant que le distinct ne soit appliqué. Merci! –

+0

Cela dit, je suis sûr qu'il existe des options pour Row_Number() pour ne pas compter les lignes exclues. Aucune idée comment le faire encore (simuler le même effet que la sous-requête distincte) –

2

Les colonnes de date et d'heure ne doivent jamais être utilisées comme clé primaire. De plus, si vous aviez une colonne indetity, vous ne pourriez pas avoir:

 PK    Data 
2010 01 01 01 New Years Day 
2010 01 01 02 Make Resolutions 
2010 01 01 03 Return Gifts 
2010 02 14 01 Valentines day 
2010 02 14 02 Buy flowers 

Comme 2010 01 01 01 aurait la même identité que 2010 02 14 01. La meilleure approche serait d'avoir une colonne d'identité à part, et d'avoir votre date de vacances dans une autre colonne, et de concaténer la valeur nvarchar convertie de chacun de ces champs.

+0

Mes excuses. Identité comme colonne. La date finit par être 2010010100 + le numéro de ligne du groupe, par ex. exactement ce que votre exemple montre. Cela finit par être le PK de la vue, que nous utilisons pour alimenter une autre table entre différents systèmes. –

+0

+1 pour le conseil. En fin de compte, cette technique exécutée plusieurs fois ne produira pas le même PK car cela dépend de l'ordre de tri. –