如何将行从表的开头移动到它的末尾?

时间:2016-11-16 14:04:33

标签: sql-server tsql

我有一张表:

tblRows (RowIndex int identity,  Data int)

获取X行并将其移动到表格末尾的最佳方法是什么? 例如,假设表中有1000行,RowIndex为1-1000。 我想将前50行移到最后,所以现在RowIndex将是51-1050。

我应该使用删除然后插入还是使用更新?

数据列必须是唯一的,因此请先删除然后插入。

行的顺序很重要。

4 个答案:

答案 0 :(得分:0)

使用insert,然后删除。

INSERT INTO tblRows(Data)
SELECT Data
FROM MyTable
WHERE RowIndex <= 50

然后,一旦您确认已添加数据,

DELETE FROM tblRows
WHERE RowIndex <= 50

答案 1 :(得分:0)

SET IDENTITY_INSERT dbo.tblRows On;  
with cte as (select top 50 RowIndex, 
                           (SELECT MAX(t.RowIndex) FROM tblRows t) + row_number() 
                           over (order by RowIndex) rn,DATA  from tblRows order by RowIndex)
    INSERT  tblRows (RowIndex, Data)  SELECT RN AS ROWINDEX, DATA  from cte;
;with cte as (select top 50 * FROM tblRows ORDER by RowIndex)
    DELETE cte;

要避免使用唯一约束,您可以查询要移动到临时表的内容,然后删除行,然后从临时表中插入。

;with cte as (select top 50 RowIndex, 
                           (SELECT MAX(t.RowIndex) FROM tblRows t) + row_number() 
                           over (order by RowIndex) rn,DATA  from tblRows order by RowIndex)
SELECT * INTO #tblRows_temp FROM cte;           

with cte as (select top 50 * FROM tblRows ORDER by RowIndex)
    DELETE cte;


SET IDENTITY_INSERT dbo.tblRows On;  
    INSERT  tblRows (RowIndex, Data)  SELECT RN AS ROWINDEX, DATA  from #tblRows_temp;
SET IDENTITY_INSERT dbo.tblRows Off;  

DROP TABLE #tblRows_temp;

答案 2 :(得分:0)

好的我想出了这个: 添加了一个RowOrder int列,因此该表现在看起来像这样:

tblRows (RowIndex int identity,  Data int,RowOrder int)

将RowOrder从1更新为1000:

update tblRows 
set RowOrder = rn
from (
       select RowOrder,
              row_number() over(order by (select RowIndex)) as rn
       from tblRows 

     ) tblRows 

创建了一个临时表,用于保存我想要移动的行:

DECLARE @TempRows TABLE (RowOrder int,Data int)    

INSERT INTO @TempRows(RowOrder,Data )
SELECT TOP (50) RowOrder,Data 
FROM tblRows 
ORDER BY RowOrder

-- delete rows
DELETE 
FROM  tblRows 
WHERE RowOrder BETWEEN 1 AND 50

-- add rows to the end of the table
INSERT INTO tblRows (RowOrder,Data )
SELECT RowOrder, Data 
FROM @TempRows 
ORDER BY RowOrder

-- update row order
UPDATE RowOrder
SET RowOrder = rn
FROM(
    SELECT RowOrder, row_number() over(order by (select RowIndex)) as rn
    FROM RowOrder    
    ) RowOrder

我很想知道是否还有其他更优雅的解决方案。

答案 3 :(得分:0)

SQL并不关心表中行的排序,你也不应该这样做。您的RowIndex字段是一个标识字段,它只是一个唯一标识符。通过查询检索/显示数据时进行排序。它存储的顺序根本不重要。并且更改记录的唯一标识符对于一致性是不利的,并且可能会破坏该数据项与其他位置(在您的数据库或其他应用程序中)保存其引用的其他记录之间的关系。

要解决此问题,您可以添加一个名为RowOrder的整数列,并在编写查询时按顺序而不是RowIndex对数据进行排序。最初使用与每行的RowIndex相同的值填充此新列。

然后,您提到要将前50条记录移动到列表末尾。因此,您只需找出RowOrder的当前最大值,然后(假设没有其他人同时向表中添加记录),请将前50个记录的RowOrder值递增该值:

DECLARE @MaxRowOrder int
SELECT @MaxRowOrder = MAX(RowOrder) FROM tblRows

UPDATE tblRows SET RowOrder = RowOrder + @MaxRowOrder WHERE RowOrder <= 50

如果你真的想要整洁,你可以编写另一个SQL来从所有RowOrder值中减去50,这样它们就会再次从1开始。

UPDATE tblRows SET RowOrder = (RowOrder - 50)

要按预定顺序检索行,这很简单:

SELECT * FROM tblRows ORDER BY RowOrder