如何重新排序sql表

时间:2015-10-23 01:35:29

标签: sql sql-server tsql

我有一个看起来像这样的表:

RecNo | TaskDesc | SeqNumber
1     |  test    | 1
2     |  test2   | 2
3     |  test3   | 3

这些项目可以使用可重新排序的网格移动,因此测试3可以变为SeqNumber 1,测试可以变为SeqNumber2。我试图找到一种方法来传递新的位置并将taskDesc的数量记录到存储过程并让它设置新位置并调整其他项目。我有点成功,但有时数字不会更新。这是我一直在尝试的样本

Update tblTasks Set SeqNum = SeqNum + 1
Where SeqNum >= @newPosition 
AND SeqNum < (Select SeqNum From tblTasks WHERE RecNo = @UpdatedRecNo)    

Update tblTasks Set SeqNum = @newPosition 
Where RecNo = @UpdatedRecNo

问题取决于你如何移动数字最终的行:

RecNo | TaskDesc | SeqNumber
    1     |  test    | 3
    2     |  test2   | 2
    3     |  test3   | 2

RecNo | TaskDesc | SeqNumber
    1     |  test    | 4
    2     |  test2   | 5
    3     |  test3   | 2

不要留在1,2,3的范围内,不要保持独特。 SeqNum用于表示紧急度1是最高的。

2 个答案:

答案 0 :(得分:2)

你需要以不同的方式处理向上移动然后向下移动:

--Store the old value for performance and to simplify code.
DECLARE @oldPosition int;
SELECT @oldPosition = SeqNum FROM tblTasks WHERE RecNo = @UpdatedRecNo;

UPDATE tblTasks
SET SeqNum = CASE
    WHEN RecNo = @UpdatedRecNo THEN @newPosition    --Put the record in the new position.
    WHEN @newPosition < @oldPosition AND SeqNum >= @newPosition AND SeqNum < @oldPosition THEN SeqNum + 1   --Move the other rows out of the way when moving to a lower position.
    WHEN @newPosition > @oldPosition AND SeqNum <= @newPosition AND SeqNum > @oldPosition THEN SeqNum - 1   --Move the other rows out of the way when moving to a higher position.
    ELSE SeqNum --No change.
    END;

这将传递所有记录一次,并且:   - 将其移动到新序列。   - 将其移动到更高的序列(如果移动记录向下移动)。   - 将其移至较低的序列(如果移动记录向上移动)。   - 把它放在原处。

如果您不想触摸所有记录,可以添加:

WHERE   (@newPosition < @oldPosition AND SeqNum >= @newPosition AND SeqNum <= @oldPosition)
    OR  (@newPosition > @oldPosition AND SeqNum <= @newPosition AND SeqNum >= @oldPosition);

这将消除对else子句的需要。

答案 1 :(得分:0)

如果你的桌子很小,那么采取暴力方法可能会更好:

with toupdate as (
      select t.*,
             row_number() over (order by (case when RecNo = @UpdatedRecNo then @newPosition + 0.5 else seqnumber end)) as newseqnumber
      from tblTasks t
     )
update toupdate
     set seqnumber = newseqnumber
     where seqnumber <> newseqnumber;