在存储过程中使用查询中项目的索引位置更新列

Update column with index position of item in query in stored procedure

我想用它所在的索引更新按特定顺序的游戏查询。我想为此使用 SP 而不是代码,因为我不想发送 1000 SQL 更新查询,而是在 SP 中使用来更新它们。

下面是我想要的一些伪代码。我需要 index 参数是游戏在 order by/where 子句中的位置。基本上当天的第一场比赛是索引1,依此类推。

UPDATE Games
Set GameId = 'G' + Index
WHERE EventId = 100
ORDER BY Date, Time

下面是执行该查询后的示例 table。请注意,前两个是第二天,因此为什么它的数字比前一天的第二行大,与时间相同。

游戏Table

Date          Time       GameId      EventId
6/22/2020     9:00 AM    G6          100
6/21/2020     8:00 AM    G2          100
6/21/2020     7:00 AM    G1          100
6/21/2020     9:00 AM    G3          100
6/21/2020     10:00 AM   G4          100
6/22/2020     8:00 AM    G5          100

您可以将 CTE 与 ROW_NUMBER 一起使用,然后将其连接回您的 table。这样就可以更新了。

WITH cte_rn 
as
(
    select [Date],[Time],[EventId],ROW_NUMBER() OVER (ORDER BY [Date],[Time]) as rn
    from [dbo].[Games]
)

UPDATE g1
SET [GameId] = 'G'+CAST(g2.rn AS VARCHAR(10))
FROM [dbo].[Games] g1
JOIN cte_rn g2
    ON g1.[Date] = g2.[Date] 
    AND g1.[Time] = g2.[Time] 
    AND g1.[EventId] = g2.[EventId] ;

您可以使用 row_number() 生成索引。在 SQL 服务器会为此推荐一个可更新的 cte:查询要短得多,并且不需要连接(这避免了第二次扫描):

with cte as (
    select gameId, concat('G', row_number() over(order by date, time)) newGameId
    from games
    where eventId = 100
)
update cte set gameId = newGameId

请注意,与+不同,concat()强制使用字符串上下文,因此无需显式转换行号。