通过 row_number() 使用 over order 更新
Posted
技术标签:
【中文标题】通过 row_number() 使用 over order 更新【英文标题】:update using over order by row_number() 【发布时间】:2018-11-18 01:51:10 【问题描述】:我找到了一些关于使用 over order by 进行更新的方法的答案,但没有任何方法可以解决我的问题。在 SQL Server 2014 中,我有一列 DATES(间隔不一致到毫秒)和一列 PRICE,因此我想用 50 行的 PRICE 值更新 OFFSETPRICE 列(按 DATES 排序) .我发现的解决方案在查询或子查询中都有超序,但我认为我需要它。或者也许我让它变得比现在更复杂。
在这个简化的例子中,如果偏移量是 3 行,那么我需要转这个:
DATES, PRICE, OFFSETPRICE
2018-01-01, 5.01, null
2018-01-03, 8.52, null
2018-02-15, 3.17, null
2018-02-24, 4.67, null
2018-03-18, 2.54, null
2018-04-09, 7.37, null
进入这个:
DATES, PRICE, OFFSETPRICE
2018-01-01, 5.01, 3.17
2018-01-03, 8.52, 4.67
2018-02-15, 3.17, 2.54
2018-02-24, 4.67, 7.37
2018-03-18, 2.54, null
2018-04-09, 7.37, null
This post 很有帮助,到目前为止,我有这段代码可以正常工作:
select dates, price, row_number() over (order by dates asc) as row_num
from pricetable;
我还没有弄清楚如何将更新值指向未来的有序行。提前感谢您的帮助。
【问题讨论】:
请发布您的数据样本和您迄今为止尝试过的查询。 【参考方案1】:LEAD 是一个有用的窗口函数,用于从后续行中获取值。 (另外,LAG,它查看前面的行,)这是您问题的直接答案:
;WITH cte AS (
SELECT dates, LEAD(price, 2) OVER (ORDER BY dates) AS offsetprice
FROM pricetable
)
UPDATE pricetable SET offsetprice = cte.offsetprice
FROM pricetable
INNER JOIN cte ON pricetable.dates = cte.dates
既然您询问了 ROW_NUMBER,下面的内容也是一样的:
;WITH cte AS (
SELECT dates, price, ROW_NUMBER() OVER (ORDER BY dates ASC) AS row_num
FROM pricetable
),
cte2 AS (
SELECT dates, price, (SELECT price FROM cte AS sq_cte WHERE row_num = cte.row_num + 2) AS offsetprice
FROM cte
)
UPDATE pricetable SET offsetprice = cte2.offsetprice
FROM pricetable
INNER JOIN cte2 ON pricetable.dates = cte2.dates
因此,您可以使用 ROW_NUMBER 对行进行排序,然后使用该结果选择前 2 行的值。 LEAD 就是直接做这件事。
【讨论】:
感谢您的帮助,马克斯。 SQL 工具箱通常比我的范围更深。以上是关于通过 row_number() 使用 over order 更新的主要内容,如果未能解决你的问题,请参考以下文章
tsql 通过row_number() over() 产生行号
在 SQL Server 2005 中使用 ROW_NUMBER() OVER () 对不同列进行排序的分页查询