T-SQL - 通过Row_Number()更新记录子集

时间:2017-04-07 13:08:25

标签: sql-server tsql

我有一个表,其中包含父表的记录子集。 每个子集都有一个存储在[rank]字段中的订单。 我需要根据字段otherRank中保存的新订单更新此表中特定子集的此字段。

以下内容如下:

update mytable t1 set
[rank] = t2.new_rank_num
from (select t2.id, new_rank_num = row_number() over (order by t2.otherRank)
    from mytable t2 where t2.parentID = 628) t2
where t1.id = t2.id

或者,我需要:

update mytable t1 set
[rank] = t2.new_rank_num
from (select t2.id, new_rank_num = row_number() over (order by t2.otherRank)
    from mytable t2 where t2.parentID = 628) t2
where t1.id = t2.id and t1.parentID = 628

我的具体问题是我不希望在parentID 628

的职权范围之外更新任何内容

修改 尝试运行时遇到错误:

  

t1附近的语法不正确   t2

附近的语法不正确

所以我认为语法必须是:

update mytable set
    [rank] = t2.new_rank_num
    from (select id, new_rank_num = row_number() over (order by otherRank)
from mytable where parentID = 628) t2
where id = t2.id and parentID = 628

修改2

好的,我按照SqlZim的建议选择了CTE解决方案。 它看起来像这样:

;with cte as (
  select t2.id, new_rank_num = row_number() over (order by t2.otherRank)
    from mytable t2 where t2.parentID = 628
)

update t1 set 
    [rank] = t2.new_rank_num
from mytable t1
inner join cte t2 on t1.id = t2.id

2 个答案:

答案 0 :(得分:3)

我更喜欢使用common table expression (cte)来执行此类操作:

;with cte as (
  select *
    , new_rank_num = row_number() over (
        partition by ParentId 
        order by otherRank
        )
  from mytable
)
update cte
set [rank] = new_rank_num
where ParentID = 628;

如果您想在运行更新之前预览更改,只需将上面更改为select而不是update。请注意,只有cte之后的第一个语句才能使用cte。

答案 1 :(得分:0)

您还可以更新视图,而不仅仅是表格。

试试这个:

UPDATE T  
SET [rank] = [new_rank_num]
FROM (
    SELECT 
       [rank]         = [rank], 
       [new_rank_num] = row_number() over (order by otherRank)
    FROM mytable 
    WHERE parentID = 628 
) T