使用row_number()

时间:2018-11-18 01:51:11

标签: sql-server

我找到了一些使用超额订购方式进行更新的方法的答案,但没有找到解决我问题的方法。在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 个答案:

答案 0 :(得分: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就是直接做那件事。

相关问题