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

问题描述 投票:2回答:4

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

例如。我在Priority专栏中有以下6条记录:

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

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

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

我怎么能在T-SQL中做到这一点?

sql sql-server
4个回答
3
投票

使用case表达式:

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

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 |

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

1
投票

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

例如。如果你使val6s优先1.5然后你不必改变任何其他行的值。

偶尔(基于更新频率),您可以使用ROW_NUMBER()重新定位整个表格,以便将值返回到ints。


例如。 rebase查询(当优先级值变得太“繁琐”时)将是这样的:

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
© www.soinside.com 2019 - 2024. All rights reserved.