2012-05-21 2 views
2

J'ai une table comme suit dans SQL Server 2008Mise à jour une colonne basée sur des valeurs dans les lignes liées

AMID    TierLevel 
--------   ------------- 
    999     GOLD 
    1000    SILVER 
    1000    GOLD 
    1000    PLATINUM 
    1000    BRONZE 
    1001    GOLD 
    1001    SILVER 
    1002    SILVER 
    1003    GOLD 

Maintenant, je veux mettre à jour ce tableau comme suit

AMID    TierLevel 
--------   ------------- 
    999     GOLD 
    1000    PLATINUM 
    1000    PLATINUM 
    1000    PLATINUM 
    1000    PLATINUM 
    1001    GOLD 
    1001    GOLD 
    1002    SILVER 
    1003    GOLD 

Voici les conditions

  • Je souhaite une valeur Tier unique pour le même AMID, et les valeurs Tier doivent être sélectionnées dans pri comme base rité

    1. PLATINUM
    2. GOLD
    3. ARGENT
    4. BRONZE
  • Cela signifie que si elle est la plus élevée ayant une présente dans ses valeurs de niveau sélectionner alors que. Comme je l'ai indiqué dans la deuxième table, platine pour 1000 et d'or pour 1001 ..

s'il vous plaît me aider

Merci,
Harry

Répondre

1

je referais ce en utilisant une table temporaire pour stocker le rang de chaque catégorie:

DECLARE @Rank TABLE (ID INT NOT NULL PRIMARY KEY, Name VARCHAR(10) NOT NULL) 
INSERT @Rank VALUES (1, 'PLATINUM'), (2, 'GOLD'), (3, 'SILVER'), (4, 'BRONZE') 

;WITH T AS 
( SELECT AMID, TierLevel, MIN(ID) OVER(PARTITION BY AMID) [MinID] 
    FROM #T 
      INNER JOIN @Rank 
       ON Name = TierLevel 
) 
UPDATE T 
SET  TierLevel = Name 
FROM T 
     INNER JOIN @Rank 
      ON ID = MinID 
WHERE TierLevel <> Name 

Cela a été fait en utilisant les données suivantes échantillon:

CREATE TABLE #T (AMID INT, TierLevel VARCHAR(10)) 
INSERT #T VALUES 
    (999, 'GOLD'), 
    (1000, 'SILVER'), 
    (1000, 'GOLD'), 
    (1000, 'PLATINUM'), 
    (1000, 'BRONZE'), 
    (1001, 'GOLD'), 
    (1001, 'SILVER'), 
    (1002, 'SILVER'), 
    (1003, 'GOLD') 
+0

Merci Gareth, celui-ci travaille gr8 pour ma table, et je voudrais vous poser une petite question ici. cela mettra-t-il à jour toutes les lignes dans la table ou les mises à jour seulement où la valeur doit être changée? parce qu'il montre 190k lignes mises à jour de ma table de 200k lignes .. !! – harry

+1

Vous pouvez facilement ajouter une clause WHERE, par ex. 'WHERE TierLevel <> Name' ... –

+0

Il aurait mis à jour toutes les lignes, donc il semble que vous ayez des lignes qui ne sont pas BRONZE, SILVER, GOLD ou Platinum! Comme Aaron l'a suggéré, j'ai ajouté une clause where pour mettre à jour la déclaration. – GarethD

2
DECLARE @amid TABLE (Amid INT, TierLevel VARCHAR(20)); 

INSERT @amid VALUES 
(999 ,'GOLD'), 
(1000,'SILVER'), (1000,'GOLD'), (1000,'PLATINUM'), (1000,'BRONZE'), 
(1001,'GOLD'), (1001,'SILVER'), 
(1002,'SILVER'), (1003,'GOLD'); 

;WITH [priority](r, n) AS 
(
    SELECT 1, 'PLATINUM' 
    UNION ALL SELECT 2, 'GOLD' 
    UNION ALL SELECT 3, 'SILVER' 
    UNION ALL SELECT 4, 'BRONZE' 
), 
per_amid(amid, h) AS 
(
    SELECT a.amid, MIN(p.r) 
     FROM @amid AS a 
     INNER JOIN [priority] AS p 
     ON a.TierLevel = p.n 
     GROUP BY a.amid 
) 
UPDATE a 
    SET TierLevel = p.n 
    FROM @amid AS a 
    INNER JOIN per_amid AS pa 
    ON a.Amid = pa.amid 
    INNER JOIN [priority] AS p 
    ON pa.h = p.r 
    -- added where clause to address question brought up on other answer 
    WHERE a.TierLevel <> p.n; 

SELECT Amid, TierLevel FROM @amid; 

Résultats:

Amid TierLevel 
---- --------- 
999 GOLD 
1000 PLATINUM 
1000 PLATINUM 
1000 PLATINUM 
1000 PLATINUM 
1001 GOLD 
1001 GOLD 
1002 SILVER 
1003 GOLD 
+0

Merci Aaron, Celui-ci travaillant gr8. :) – harry

+0

@harry alors pourquoi l'avez-vous accepté, puis ne pas l'accepter, puis accepter l'autre réponse qui est juste parce que j'ai aidé? –

+0

Ouch ..! désolé compagnon, je pensais pouvoir marquer les deux comme réponses, d'abord j'ai cliqué sur le vôtre et puis l'autre, pourrait-il garder le second .. et je ne l'ai pas remarqué .. :( – harry

Questions connexes