考虑一个包含以下列的表:
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并更新他的新老排名之间的每一行?
答案 0 :(得分:2)
这是另一种方法。这将避免重复键问题(假设您对Rank有唯一约束)。如果排名低于当前排名,则更新为工作。
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
答案 1 :(得分:1)
是否可以根据您可以订购的其他列动态计算yoru排名?如果是这样,那么您可以在某些RDBMS中使用ROW_NUMBER函数来相应地计算和更新您的排名。
如果没有,另一种方法(作弊的类型)将使用小数作为你的等级,并指定Ben的值为1.5 :)这假设你没有直接从你的数据库显示等级。
答案 2 :(得分:1)
由于有一些来回,我就是这样做的(使用SQL Server表示法):
SELECT @CurrentRank = Rank FROM TableName WHERE Id = @SelectedId
UPDATE TableName
SET Rank=
CASE
WHEN Id = @SelectedId THEN @NewSelectedRank
WHEN @NewSelectedRank < @CurrentRank
AND Rank >= @NewSelectedRank AND Rank < @CurrentRank
THEN Rank = Rank + 1
WHEN @NewSelectedRank > @CurrentRank
AND Rank <= @NewSelectedRank AND Rank > @CurrentRank
THEN Rank = Rank - 1
END
答案 3 :(得分:1)
如果你想对它有所不必要(或者有其他理由这样做),你可以计划只用一个更新查询来更新被移动的单行的等级,你可以使用一个触发器强制其他行更新。这将按如下方式完成:
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
我基本上想指出它可以通过某种方式完成,而不是建议这样做。如果您不熟悉将应用于表格的所有其他逻辑,则不建议这样做;如果这是一个包含其他事情的大型项目,您可能需要非常小心,因为触发器可能很复杂。