我有一个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
语句?我可以使用游标和循环来做到这一点,但它看起来效率不高。
答案 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