我有一个SQL Server表,其中包含一个名为Priority
(int
)的列,其值为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中做到这一点?
使用case
表达式:
update tablename
set Priority = case when Priority = 6 then 2
when Priority > 1 then Priority + 1
else Priority
end
如果您使用的是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 |
我想你想要一般情况的答案(不是特别是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
我实际上建议将Priority
设为float
,以便在特殊情况下,您始终可以计算任何现有相邻值之间的新优先级值。
例如。如果你使val6
s优先1.5
然后你不必改变任何其他行的值。
偶尔(基于更新频率),您可以使用ROW_NUMBER()
重新定位整个表格,以便将值返回到int
s。
例如。 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