删除操作后使用算术数字序列更新列的有效方法

时间:2011-09-29 06:51:52

标签: sql-server tsql

我有一个PresentationSlide表:

PresentationSlide
    PresentationSlideId
    PresentationId
    Content
    Order

和示例行:

+---------------------+----------------+---------+-------+
| PresentationSlideId | PresentationId | Content | Order |
+--------+------------+----------------+---------+-------+
|                 123 |              3 | "bla"   |     1 |
|                  23 |              3 | "bla2"  |     2 |
|                  22 |              3 | "bla3"  |     3 |
|                 100 |              3 | "bla4"  |     4 |
|                 150 |              3 | "bla5"  |     5 |
+---------------------+----------------+---------+-------+    

我希望在Order操作后在DELETE列中维护数字的算术序列(1,2,3,4,...)。

例如,如果我删除第三行(PresentationSlideId = 22),则订单列中的值将为:(1,2,4,5)我想以这种方式更新Order

PresentationSlideId = 100:  update order from 4 to 3
PresentationSlideId = 150:  update order from 5 to 4

如何最有效地进行此类更新?有没有办法只使用一个UPDATE语句?我可以使用游标和循环来做到这一点,但它看起来效率不高。

2 个答案:

答案 0 :(得分:2)

;with C as
(
  select [Order],    
         row_number() over(order by [Order]) as rn
  from PresentationSlide 
)
update C set
  [Order] = rn

答案 1 :(得分:2)

1)订单是一个非常糟糕的列名,因为它是一个SQL关键字

2)如果能够处理顺序中的间隙(并且可能切换到使用浮点数,因此可以插入小数值)会更好,因为在当前模型中,每次插入,更新或删除都是可能会影响整个表格。这不能很好地扩展。在选择期间使用ROW_NUMBER()计算订单通常会更好。

3)

create table #PresentationSlide (
    PresentationSlideID int not null,
    PresentationId int not null,
    Content varchar(10) not null,
    [Order] int not null
)
insert into #PresentationSlide (PresentationSlideId , PresentationId , Content , [Order])
select 123,3,'bla',1 union all
select 23,3,'bla2',2 union all
select 22,3,'bla3',3 union all
select 100,3,'bla4',4 union all
select 150,3,'bla5',5


delete from #PresentationSlide where PresentationSlideId = 22

;With Reorder as (select PresentationSlideId,ROW_NUMBER() OVER (ORDER BY [Order]) as NewOrder from #PresentationSlide)
update ps set [Order] = NewOrder
from #PresentationSlide ps inner join Reorder r on ps.PresentationSlideId = r.PresentationSlideId

select * from #PresentationSlide order by [Order]

drop table #PresentationSlide