我有一个SQL Server表,其中包含一个名为Priority
(int
)的列,其值从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中执行此操作?
答案 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