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