如何使用秩列维护有序列表?(sql)
考虑一个包含以下列的表:如何使用秩列维护有序列表?(sql),sql,Sql,考虑一个包含以下列的表: ID, Name, Rank 以及以下数据: 100, John, 1 200, Steve, 2 300, Mike, 3 400, Ben, 4 500, Jake, 5 排名是独一无二的 如果我想给Ben一个2的排名并相应地更新其余的,那么更新表的最佳方式是什么 100, John, 1 400, Ben, 2 200, Steve, 3 300, Mike, 4 500, Jake, 5 有没有比将Ben的排名改为2并更新新旧排名之间的每一行更聪明的方法
ID, Name, Rank
以及以下数据:
100, John, 1
200, Steve, 2
300, Mike, 3
400, Ben, 4
500, Jake, 5
排名是独一无二的
如果我想给Ben一个2的排名并相应地更新其余的,那么更新表的最佳方式是什么
100, John, 1
400, Ben, 2
200, Steve, 3
300, Mike, 4
500, Jake, 5
有没有比将Ben的排名改为2并更新新旧排名之间的每一行更聪明的方法 是否可以根据您可以订购的其他列动态计算您的排名?如果是这样,那么您可以在一些RDBMS中使用ROW_NUMBER函数来相应地计算和更新您的排名
如果不是,另一种方法(一种欺骗)是对你的排名使用小数,并给Ben分配一个值1.5:)这是假设你没有直接从数据库中显示排名。你的排名能够根据你可以排序的其他列动态计算吗?如果是这样,那么您可以在一些RDBMS中使用ROW_NUMBER函数来相应地计算和更新您的排名
如果不是,另一种方法(有点欺骗)是对你的排名使用小数,并给Ben赋值1.5:)这是假设你没有直接从数据库显示排名。由于有一些来回,我会这样做(使用SQL Server表示法):
从TableName中选择@CurrentRank=Rank,其中Id=@SelectedId
更新表名
设置秩=
案例
当Id=@SelectedId时,则为@newselectedBank
当@NewSelectedRank<@CurrentRank
和Rank>=@NewSelectedRank和Rank<@CurrentRank
然后秩=秩+1
当@NewSelectedRank>@CurrentRank
和Rank@CurrentRank
然后秩=秩-1
结束
由于有一些反复,我将这样做(使用SQL Server表示法):
从TableName中选择@CurrentRank=Rank,其中Id=@SelectedId
更新表名
设置秩=
案例
当Id=@SelectedId时,则为@newselectedBank
当@NewSelectedRank<@CurrentRank
和Rank>=@NewSelectedRank和Rank<@CurrentRank
然后秩=秩+1
当@NewSelectedRank>@CurrentRank
和Rank@CurrentRank
然后秩=秩-1
结束
这里是另一种方法。这将避免重复密钥问题(假设您对秩有唯一的约束)。如果等级低于当前等级,则更新为工作
DECLARE @ID int, @NewRank int, @CurrentRank int, @LowRank int, @HighRank int
SET @ID=400
SET @NEWRANK=2
SELECT @CurrentRank = Rank FROM MyTable WHERE Id = @ID
SET @LowRank = CASE WHEN @NewRank < @CurrentRank THEN @NewRank ELSE @CurrentRank END
SET @HighRank = CASE WHEN @NewRank < @CurrentRank THEN @CurrentRank ELSE @NewRank END
UPDATE MyTable SET Rank = -Rank WHERE Rank BETWEEN @LowRank AND @HighRank
UPDATE MyTable SET Rank = @NewRank WHERE ID = @ID
UPDATE MyTable SET Rank =
CASE
WHEN @NewRank < @CurrentRank THEN -Rank + 1
ELSE -Rank - 1
END
WHERE Rank < 0
声明@ID int、@NewRank int、@CurrentRank int、@LowRank int、@HighRank int
设置@ID=400
设置@NEWRANK=2
从MyTable中选择@CurrentRank=Rank,其中Id=@Id
当@NewRank<@CurrentRank然后@NewRank ELSE@CurrentRank END时设置@LowRank=CASE
当@NewRank<@CurrentRank然后@CurrentRank ELSE@NewRank END时,设置@HighRank=CASE
更新MyTable SET Rank=-Rank,其中排名介于@LowRank和@HighRank之间
更新MyTable SET Rank=@NewRank,其中ID=@ID
更新MyTable集合排名=
案例
当@NewRank<@CurrentRank时,则为-Rank+1
ELSE-排名-1
结束
其中秩<0
这里是另一种方法。这将避免重复密钥问题(假设您对秩有唯一的约束)。如果等级低于当前等级,则更新为工作
DECLARE @ID int, @NewRank int, @CurrentRank int, @LowRank int, @HighRank int
SET @ID=400
SET @NEWRANK=2
SELECT @CurrentRank = Rank FROM MyTable WHERE Id = @ID
SET @LowRank = CASE WHEN @NewRank < @CurrentRank THEN @NewRank ELSE @CurrentRank END
SET @HighRank = CASE WHEN @NewRank < @CurrentRank THEN @CurrentRank ELSE @NewRank END
UPDATE MyTable SET Rank = -Rank WHERE Rank BETWEEN @LowRank AND @HighRank
UPDATE MyTable SET Rank = @NewRank WHERE ID = @ID
UPDATE MyTable SET Rank =
CASE
WHEN @NewRank < @CurrentRank THEN -Rank + 1
ELSE -Rank - 1
END
WHERE Rank < 0
声明@ID int、@NewRank int、@CurrentRank int、@LowRank int、@HighRank int
设置@ID=400
设置@NEWRANK=2
从MyTable中选择@CurrentRank=Rank,其中Id=@Id
当@NewRank<@CurrentRank然后@NewRank ELSE@CurrentRank END时设置@LowRank=CASE
当@NewRank<@CurrentRank然后@CurrentRank ELSE@NewRank END时,设置@HighRank=CASE
更新MyTable SET Rank=-Rank,其中排名介于@LowRank和@HighRank之间
更新MyTable SET Rank=@NewRank,其中ID=@ID
更新MyTable集合排名=
案例
当@NewRank<@CurrentRank时,则为-Rank+1
ELSE-排名-1
结束
其中秩<0
如果您想对它产生不必要的幻想(或者有其他理由这样做),并且您可以计划只使用单个更新查询更新正在移动的单行的列组,您可以使用触发器强制其他行更新。这将按以下方式进行:
CREATE OR REPLACE TRIGGER [dbo].[tr_RankChange]
ON [dbo].[table_name] Before UPDATE AS
BEGIN
Update [dbo].[table_name] Set Rank = Rank + 1 Where rank >= New.Rank
Update [dbo].[table_name] Set Rank = Rank - 1 Where rank >= Old.Rank
END
我基本上是想指出,这是可以做的事情的方式,不建议这样做。如果您不熟悉将应用于该表的所有其他逻辑,则不建议使用该选项;如果这是一个有其他事情在进行的大型项目,您可能需要非常小心,因为触发器可能很复杂 如果您想对它产生不必要的幻想(或者有其他理由这样做),并且您可以计划只使用单个更新查询更新正在移动的单行的列组,您可以使用触发器强制其他行更新。这将按以下方式进行:
CREATE OR REPLACE TRIGGER [dbo].[tr_RankChange]
ON [dbo].[table_name] Before UPDATE AS
BEGIN
Update [dbo].[table_name] Set Rank = Rank + 1 Where rank >= New.Rank
Update [dbo].[table_name] Set Rank = Rank - 1 Where rank >= Old.Rank
END
我基本上是想指出,这是可以做的事情的方式,不建议这样做。如果您不熟悉将应用于该表的所有其他逻辑,则不建议使用该选项;如果这是一个有其他事情在进行的大型项目,您可能需要非常小心,因为触发器可能很复杂 在哪个基础上,您决定rankIt看起来只是另一个字段。排名上是否有“唯一”索引约束?是的,至少我认为它应该是唯一的,因为不应该有两行具有相同排名。是的,它只是另一列。在此基础上,您决定rankIt看起来只是另一个字段。排名上是否有“唯一”索引约束?是的,至少我认为它应该是唯一的,因为不应该有两行具有相同排名。是的,它只是另一列。不,它们只是用户可以分配给行的“等级”(想想一个用户界面,您可以在其中拖放列表项来“排列”它们)-我不确定我是否理解有小数等级的意义。小数等级允许您在两行之间更新一行,而不接触任何其他行。例如,如果您知道Ben介于John和Steve之间,并且您知道Steve的值为2,那么