更改行的排序顺序后如何重新排列“排序顺序”列

时间:2018-09-18 08:06:35

标签: sql sql-server sorting tsql

我有一张表,其中有很多行,列调用“ 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

2 个答案:

答案 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

Here are some tests

可以通过在上面添加ROW_NUMBER()来解决空白和重叠。

Some moar tests