如何使用SQL重新排序行(不是交换)

时间:2013-11-19 15:56:24

标签: sql-server tsql

我需要重新排序表格中的项目,如下例所示:

Original:
Id    Pos (int)
---------
a     1
b     2
c     3
d     4
e     5

I need this result after moving d to the second row:
Id    Pos (int)
---------
a     1
b     3
c     4
d     2
e     5

正如你所看到的,它不是一个简单的交换,我需要在插入位置后将位置增加1,并在插入之前保留行。我试着这样解决它:

UPDATE [Table] SET Pos = 2 WHERE Id = 'd'

MERGE INTO [Table] T USING
(
    SELECT ROW_NUMBER() OVER(ORDER BY Pos) AS Position, Id FROM [Table]
) S
ON T.Id = S.Id
WHEN MATCHED THEN UPDATE SET Pos = S.Position;

然而,更新后两行具有相同的位置。它可能无法正确排序。

您可以使用以下脚本生成示例数据:

CREATE TABLE [Table] (
  Id char NOT NULL,
  Pos int NOT NULL,
  CONSTRAINT [PK_Table_Id] PRIMARY KEY CLUSTERED ([Id])
)
GO
INSERT INTO [Table] (Id, Pos) VALUES ('a', 1),('b', 2),('c', 3),('d', 4),('e', 5)

1 个答案:

答案 0 :(得分:7)

DECLARE @id CHAR(1) = 'd';
DECLARE @newpos INT = 2;
DECLARE @oldpos INT;

BEGIN TRANSACTION
  SELECT @oldpos = Pos FROM Table WHERE id = @id;
  IF @newpos < @oldpos 
    UPDATE #Table SET Pos = Pos + 1 
     WHERE Pos >= @newpos AND Pos < @oldpos;
  ELSE
    UPDATE #Table SET Pos = Pos - 1 
     WHERE Pos >= @newpos AND Pos > @oldpos;

  UPDATE #Table SET Pos = @newpos
   WHERE Id = @id;
COMMIT TRANSACTION