Sql server 删除操作后用算术数列更新列的有效方法

Sql server 删除操作后用算术数列更新列的有效方法,sql-server,tsql,Sql Server,Tsql,我有一张演示幻灯片: 和示例行: +---------------------+----------------+---------+-------+ | PresentationSlideId | PresentationId | Content | Order | +--------+------------+----------------+---------+-------+ | 123 | 3 | "bla" | 1

我有一张演示幻灯片:

和示例行:

+---------------------+----------------+---------+-------+
| PresentationSlideId | PresentationId | Content | Order |
+--------+------------+----------------+---------+-------+
|                 123 |              3 | "bla"   |     1 |
|                  23 |              3 | "bla2"  |     2 |
|                  22 |              3 | "bla3"  |     3 |
|                 100 |              3 | "bla4"  |     4 |
|                 150 |              3 | "bla5"  |     5 |
+---------------------+----------------+---------+-------+    
我想维护数字1,2,3,4的算术序列,。。。在“删除”操作后的“订单”列中

例如,如果我删除第三行PresentationsSlideId=22,order列中的值将为:1,2,4,5我希望通过以下方式更新order:

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

如何最有效地进行此类更新?只使用一条UPDATE语句是否有办法做到这一点?我可以使用游标和循环来实现这一点,但它似乎效率不高。

1 Order是一个非常糟糕的列名称,因为它是一个SQL关键字

;with C as
(
  select [Order],    
         row_number() over(order by [Order]) as rn
  from PresentationSlide 
)
update C set
  [Order] = rn
2如果您可以处理顺序中的间隙,并可能切换到使用浮点,这样您就可以插入分数,因为在当前模型中,每次插入、更新或删除都可能会影响整个表,这会好得多。这不能很好地扩展。在选择期间使用计算订单通常会更好

三,


对于列来说,1 Order是一个非常糟糕的名称,因为它是SQL关键字

2如果您可以处理顺序中的间隙,并可能切换到使用浮点,这样您就可以插入分数,因为在当前模型中,每次插入、更新或删除都可能会影响整个表,这会好得多。这不能很好地扩展。在选择期间使用计算订单通常会更好

三,


广告2:我不确定使用浮点数和分数是否是个好主意。据我所知,float的精度是有限的,所以在fixed one之后多次插入行之后,“Order”的派系值将开始相同。其余的都没问题。@Lucasus-int的精度也是有限的。如果浮动使你感到不舒服,可能会考虑将初始订单值分配为10的倍数。无论采用哪种方法,其目的都是允许使用可用的间隙执行大量插入和更新,并且不必每次都执行重新编号操作,但可以降低操作的平均成本。请注意:您的代码只使用一种表示形式,我添加了一个WHERE PresentationId=@PresentationId表达式,其中@PresentationId是已删除行的PresentationId,现在它可以工作,但只有当所有已删除行共享相同的PresentationId。Ad 2:我不确定使用浮点值和分数值是否是个好主意。据我所知,float的精度是有限的,所以在fixed one之后多次插入行之后,“Order”的派系值将开始相同。其余的都没问题。@Lucasus-int的精度也是有限的。如果浮动使你感到不舒服,可能会考虑将初始订单值分配为10的倍数。无论采用哪种方法,其目的都是允许使用可用的间隙执行大量插入和更新,并且不必每次都执行重新编号操作,但可以降低操作的平均成本。请注意:您的代码只使用一种表示形式,我添加了一个WHERE-PresentationId=@PresentationId表达式,其中@PresentationId是已删除行的PresentationId,现在它可以工作,但只有当所有已删除行共享相同的PresentationId时。
;with C as
(
  select [Order],    
         row_number() over(order by [Order]) as rn
  from PresentationSlide 
)
update C set
  [Order] = rn
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