根据SQL Server中的新旧值更新其他记录的优先级

时间:2017-12-22 08:24:00

标签: sql sql-server

我有一个SQL Server表,其中包含一个名为Priorityint)的列,其值从1到n。

E.g。我在Priority列中有以下6条记录:

Col1 | Priority
-----+----------
val1 | 1
val2 | 2
val3 | 3
val4 | 4
val5 | 5
val6 | 6

现在如果我想改变第6条记录的优先级2,那么在2之后所有记录的优先级应该增加1.因此输出将是

Col1 | Priority
-----+---------
val1 | 1
val6 | 2
val2 | 3
val3 | 4
val4 | 5
val5 | 6

如何在T-SQL中执行此操作?

4 个答案:

答案 0 :(得分:3)

使用case表达式:

update tablename
set Priority = case when Priority = 6 then 2
                    when Priority > 1 then Priority + 1
                    else Priority
               end

答案 1 :(得分:2)

如果您使用的是SQL Server 2012 +,则可以使用CASE表达式或IIF()

CREATE TABLE P (
    Col1 VARCHAR(25),
    Priority INT
    );
INSERT INTO P VALUES
('val1', 1),
('val2', 2),
('val3', 3),
('val4', 4),
('val5', 5),
('val6', 6);

UPDATE P
SET Priority = IIF(Priority = 6, 2, IIF(Priority = 1, 1, Priority + 1) );

SELECT *
FROM P
ORDER BY Priority;

输出:

| Col1 | Priority |
|------|----------|
| val1 |        1 |
| val6 |        2 |
| val2 |        3 |
| val3 |        4 |
| val4 |        5 |
| val5 |        6 |

答案 2 :(得分:1)

我想你想要一般情况的答案(不是特别是6和2) 例如,如果您将替换5和2,则不应增加优先级6 ...

DECLARE @PrioriyToChange int = 6;
DECLARE @NewPrioriy int = 2;
update PriorityTable set prioirity = 
                case when prioirity = @PrioriyToChange then @NewPrioriy
                     when prioirity between @NewPrioriy and @PrioriyToChange - 1 
                          then prioirity + 1
                     else prioirity
                end

答案 3 :(得分:1)

我实际上建议将Priority设为float,以便在特殊情况下,您始终可以计算任何现有相邻值之间的新优先级值。

E.g。如果您val6的优先级为1.5,那么您就不必更改任何其他行的值。

偶尔(根据更新频率),您可以使用ROW_NUMBER()重新定位整个表格,以便将值恢复为int

E.g。 rebase查询(当优先级值变得过高时,#34; fiddly")将是这样的:

declare @t table (Val char(4), Priority float)
insert into @t (Val,Priority) VALUES
('val1',1),
('val6',1.5),
('val2',2)

;With ForUpdate as (
    select *,ROW_NUMBER() OVER (ORDER BY Priority) as NewPri
    from @t
)
UPDATE ForUpdate SET Priority = NewPri
select * from @t