2011-09-29 49 views
1

后更新与数等差数列列我有一个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 | 
+---------------------+----------------+---------+-------+  

我想保持数等差数列(1 ,2,3,4,...)在Order列后DELETE操作。

例如,如果我删除第三行(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

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 
+0

广告2:我不知道,如果使用float和分数值是不错的主意。据我所知,float具有有限的精度,因此在固定行之后多次插入行后,'Order'派系值将开始相同。剩下的就好了。 –

+0

@Lacasus - 整数也具有有限的精度。如果花车让你感觉不舒服,可以考虑将初始'Order'值赋值为10的倍数。不管怎样,这个想法是允许使用可用间隙执行一些插入和更新,并且不必执行重新编号操作*每*次(您可能仍需执行重新编号,但可降低操作的*平均成本) –

+0

小备注:您的代码仅适用于一个演示文稿,我添加了“WHERE PresentationId = @PresentationId”表达式,其中@PresentationId是已删除行的PresentationId,现在它可以工作(但只有当所有已删除的行共享相同的PresentationId时)。 –

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