根据相关行中的值更新列

时间:2012-05-21 15:11:00

标签: sql sql-server-2008 sql-update rows

我在SQL Server 2008中有如下表格

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

现在我想更新此表,如下所示

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

这里的条件是

  • 我想要同一个AMID的唯一层值,并且应该在优先级基础中选择层值,如

    1. PLATINUM
    2. GOLD
    3. SILVER
    4. BRONZE
  • 这意味着如果它的Tier值中存在最高的那个,那么选择它。就像我在第二张表中所示,Platinum为1000,Gold为1001 ..

请帮我解决这个问题

谢谢,
哈利

2 个答案:

答案 0 :(得分: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;

结果:

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

答案 1 :(得分:1)

我会使用临时表来存储每个层的等级:

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

这是使用以下样本数据完成的:

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')