首页 > 解决方案 > SQL Server:按计划更新排名

问题描述

下表由工作及其各自的“等级”组成:

N   PO      Status
1   110217  Planned
2   110217  Planned
3   108999  Planned
4   108999  Planned
5   108999  Planned
6   108999  Planned
7   110225  Planned
8   110219  Planned
9   110219  Planned
10  110235  Planned
11  110236  Planned
12  110047  Planned
13  110048  Planned

我有一个不同的应用程序,用于Status在工作完成后将列更新为“已完成”。我每晚调用一个存储过程,N将当天已完成的所有作业更新为 0。它看起来像这样:

N   PO      Status
0   110217  Completed
0   110217  Completed
3   108999  Started
0   108999  Completed
0   108999  Completed
6   108999  Planned
7   110225  Planned
8   110219  Planned
9   110219  Planned
10  110235  Planned
11  110236  Planned
12  110047  Planned
13  110048  Planned

因此,最初,它N来自使用窗口函数的不同表的插入。我希望能够在第二天更新排名,将所有剩余订单转移到新的位置。如果我在这里运行此代码:

SELECT 
ROW_NUMBER() OVER (ORDER BY N) AS N*, *
FROM MyData 
WHERE N <> 0

然后我得到了我想要的结果。这是:

N*  PO      Status
1   108999  Started
2   108999  Planned
3   110225  Planned
4   110219  Planned
5   110219  Planned
6   110235  Planned
7   110236  Planned
8   110047  Planned
9   110048  Planned

问题是我无法使用窗口函数更新表列。有什么解决方法吗?是否可以模仿 的逻辑ROW_NUMBER()?这里的视图是不可能的,因为我使用的第三方应用程序不适用于 SQL 视图。

最后一件事要注意:这里的数据集是针对一个特定类别的。我的数据有几个类别都需要发生相同的逻辑,所以我还PARTITION BY需要ROW_NUMBER()

标签: sql-servertsqlssmsrow-number

解决方案


尝试以下操作:

UPDATE T
SET T.N = T.New_N
FROM 
(
    SELECT N, ROW_NUMBER() OVER (ORDER BY N) AS New_N
    FROM updated_status_table
    WHERE N <> 0
) T

您还可以使用 CTE 进行如下更新:

;WITH CTE  AS
(
    SELECT N, ROW_NUMBER() OVER (ORDER BY N) AS RN
    FROM updated_status_table
    WHERE N <> 0
)
UPDATE CTE SET N = RN
FROM CTE

请在此处查看 db<>fiddle 。

PS您可以partition by根据您的要求添加。


推荐阅读