我有一张表,其中有很多行,列调用“ order”(从1到XX)取决于我表中有多少行。
问题是,如果我想将“顺序” 1的行移动到位置3,则需要其他行中的另一个“顺序”来重新排列自己。
例如,如果我将“ order” 1移为“ 3”,则之后的所有数字都必须增加1,第二个数字现在必须为“ order” 1。
我希望我很清楚。
感谢您的帮助!
编辑/示例数据
Name | Order
Line 1 | 1
Line 2 | 2
Line 3 | 3
Line 4 | 4
如果我将“第1行”的订单更新为4而不是1,我希望其他订单的订单更新!
Name | Order
Line 2 | 1
Line 3 | 2
Line 4 | 3
Line 1 | 4
如果我将“第4行”的顺序更新为1,也是如此!
Name | Order
Line 4 | 1
Line 1 | 2
Line 2 | 3
Line 3 | 4
例如,如果我将“第3行”的顺序更新为2,则也是如此!
Name | Order
Line 1 | 1
Line 3 | 2
Line 2 | 3
Line 4 | 4
答案 0 :(得分:2)
尝试这种方法
DECLARE @tbl TABLE([Name] VARCHAR(100),[Order] INT);
INSERT INTO @tbl VALUES
('Line 1',1)
,('Line 2',2)
,('Line 3',3)
,('Line 4',4);
DECLARE @OldPos INT=3, @NewPos INT=2;
WITH cte AS
(
SELECT [Name]
,[Order]
,ROW_NUMBER() OVER(ORDER BY CASE WHEN [Order]=@OldPos
THEN CAST(@NewPos AS FLOAT)
+ CASE WHEN @OldPos<@Newpos
THEN 0.5 ELSE -0.5 END
ELSE CAST([Order] AS FLOAT) END) AS ComputedPos
FROM @tbl
)
UPDATE cte SET [Order] = ComputedPos
WHERE [Order]<>ComputedPos;
SELECT * FROM @tbl ORDER BY [Order];
这使用了可更新的CTE 。 Damian_The_Unbeliever 的评论使我有了这个想法,而无需更改订单的数据类型。
函数ROW_NUMBER
将在其OVER
子句中进行一些计算。如果[Order]
具有正确的输入值,我们将通过在新位置上添加0.5
或-0.5
在新邻居之间设置新位置。这取决于您要移动行的方向。
答案 1 :(得分:1)
您可以使用CASE
语句:
UPDATE ...
SET [Order] = [Order] + CASE
WHEN [Order] = @OLDPOS THEN @NEWPOS - @OLDPOS
WHEN @NEWPOS > @OLDPOS AND [Order] > @OLDPOS AND [Order] <= @NEWPOS THEN -1
WHEN @NEWPOS < @OLDPOS AND [Order] < @OLDPOS AND [Order] >= @NEWPOS THEN 1
ELSE 0
END
可以通过在上面添加ROW_NUMBER()
来解决空白和重叠。