2008-12-01 7 views
2

Si j'ai une table où les cellules dans une colonne ne doivent pas avoir les mêmes valeurs, comment puis-je vérifier cela et mettre à jour? (Je sais que je peux définir des contraintes dans les paramètres, mais je ne veux pas le faire.)T-SQL: Comment rendre les valeurs de cellule uniques?

Dites le nom de la colonne est appelée nom de hachage unique, et contient

 
Peter 
Peter 
Peter 
Dave 
Dave 

et ainsi de suite. Je veux que cela se transforme en:

 
Peter 
Peter1 
Peter2 
Dave 
Dave1 

Quel est le T-SQL pour SQL Server pour faire cela?

Mise à jour: Pour plus de clarté, appelons la table "Persons" et la cellule que je veux unique "UniqueName". Pourriez-vous en faire une déclaration SELECT, afin que je puisse tester le résultat avant la mise à jour. Et j'utilise SQL Server 2005 et au-dessus.

+0

Est-ce SQL Server 2005? Si c'est le cas, il vous suffit de lancer l'instruction "sélection interne" de mon exemple très simple et propre ci-dessous ... vous aurez ce que vous voulez. –

+0

Vous devez spécifier votre version de SQL Server (2000, 2005) pour obtenir une réponse plus rapide. –

+0

A ce stade, peu importe ... J'ai posté une solution 2000 et 2005 ... celle de 2000 va fonctionner sur les deux versions (et sql 7 et 2008 ... pourquoi pas). –

Répondre

5

EDIT: J'ai modifié la requête pour utiliser les noms de vos champs et ajouté une requête "select-only" pour que vous puissiez prévisualiser.

Ceci est en fait assez facile à faire ... il suffit d'utiliser ROW_NUMBER() avec une clause PARTITION:

UPDATE Persons SET UniqueName = temp.DeDupded FROM 
    (SELECT ID, 
     CASE WHEN ROW_NUMBER() OVER 
      (PARTITION BY UniqueName ORDER BY UniqueName) = 1 THEN UniqueName 
     ELSE UniqueName + CONVERT(VARCHAR, ROW_NUMBER() 
      OVER (PARTITION BY UniqueName ORDER BY UniqueName)-1) END AS DeDupded 
    FROM Persons) temp 
WHERE Persons.ID = temp.ID 

Si vous voulez un "select-only", alors là, vous allez:

SELECT ID, 
    CASE WHEN ROW_NUMBER() OVER 
     (PARTITION BY UniqueName ORDER BY UniqueName) = 1 THEN UniqueName 
    ELSE UniqueName + CONVERT(VARCHAR, ROW_NUMBER() 
     OVER (PARTITION BY UniqueName ORDER BY UniqueName)-1) END AS DeDupded 
FROM Persons 

EDIT Encore une fois: Si vous cherchez une solution SQL Server 2000 ...

CREATE TABLE #Persons (ID INT IDENTITY(1, 1), UniqueName VARCHAR(100)) 

INSERT INTO #Persons VALUES ('Bob') 
INSERT INTO #Persons VALUES ('Bob') 
INSERT INTO #Persons VALUES ('Bob') 
INSERT INTO #Persons VALUES ('John') 
INSERT INTO #Persons VALUES ('John') 

SELECT 
    ID, 
    CASE WHEN Position = 0 THEN UniqueName 
     ELSE UniqueName + (CONVERT(VARCHAR, Position)) 
    END AS UniqueName 
FROM 
    (SELECT 
     ID, 
     UniqueName, 
     (SELECT COUNT(*) FROM #Persons p2 WHERE 
      p1.UniqueName = p2.UniqueName AND p1.ID > p2.ID) AS Position 
    FROM 
     #Persons p1) _temp 

DROP TABLE #Persons 
+0

Vous devez mentionner que c'est uniquement SQL Server 2005 et supérieur. – Tomalak

+1

Peut-être que vous devriez voter contre des solutions qui ne fonctionnent pas, et pas celles que vous n'avez pas aimées. Si vous voulez être fier de quelque chose allez-y et construisez une solution aussi simple * et * fonctionne sur SQL Server 2000. – Tomalak

+0

Certes, votre solution a produit le résultat final, mais une réponse est votée pour ses moyens ainsi que sa fin. –

0

Cela ressemble à un cas d'utilisation assez clair pour un trigger (insert, mise à jour).

Questions connexes