基于row_number()更新列

时间:2015-05-28 11:25:16

标签: sql-server sql-update row-number

我为我的表创建了一个新的非空列,默认值为0,它保持显示顺序。我想更新该表的所有行,displayorder的id值为row_number()。在这里我可以为一个id做这个。我怎么能为所有ID做到这一点。

我的表是:

id | personid | name   | displayorder
---+----------+--------+------------
 1 |    10    | test1  |    0
 2 |    10    | test2  |    0
 3 |    10    | test3  |    0
 4 |    10    | test4  |    0
 5 |    10    | test5  |    0
 6 |    11    | test6  |    0
 7 |    11    | test7  |    0
 8 |    12    | test8  |    0

我希望结果是:

id | personid | name   | displayorder
---+----------+--------+------------
 1 |    10    | test1  |    1
 2 |    10    | test2  |    2
 3 |    10    | test3  |    3
 4 |    10    | test4  |    4
 5 |    10    | test5  |    5
 6 |    11    | test6  |    1
 7 |    11    | test7  |    2
 8 |    12    | test8  |    1

这是我的sql代码,但它只适用于一个给定的id:

update MyTable
set displayorder = z.ord
 FROM  (
   SELECT row_number() over (order by id) as ord, id 
     FROM MyTable p2
   where p2.personid = 1
   ) z
  where MyTable.id= z.id
  and personid = 1

3 个答案:

答案 0 :(得分:7)

使用此代码:

 Create  TABLE #order
    (
        Id INT,
        PersonId INT,
        Name NVARCHAR(25),
        DisplayOrder INT
    )

    INSERT INTO #ORDER VALUES(1 , 10 , 'test1',0 )
    INSERT INTO #ORDER VALUES(2 , 10 , 'test2',0 )
    INSERT INTO #ORDER VALUES(3 , 10 , 'test3',0 )
    INSERT INTO #ORDER VALUES(4 , 10 , 'test4',0 )
    INSERT INTO #ORDER VALUES(5 , 10 , 'test5',0 )
    INSERT INTO #ORDER VALUES(6 , 11 , 'test6',0 )
    INSERT INTO #ORDER VALUES(7 , 11 , 'test7',0 )
    INSERT INTO #ORDER VALUES(8 , 12 , 'test8',0 )



 update #order 
    Set #order.DisplayOrder=R.DisplayOrder
    from(select id,ROW_NUMBER() over (partition by S.personid  order by S.id) as DisplayOrder
    from #order S) R
    where #order.Id=R.id

    select * from #order

答案 1 :(得分:3)

如果productpropertyMyTable真的是同一张桌子,我会这样做:

with cte as (
    select
        t.displayorder,
        row_number() over(partition by t.PersonId order by t.Id) as rn
    from MyTable as t
)
update cte set displayorder = rn

这个使用公共表表达式被视为SQL Server中可更新视图的事实。

甚至可以使用row_number()作为displayorder创建视图,因此会自动重新计算,因此每次添加/删除行时都不必更新表格。

答案 2 :(得分:1)

快速解决方案是使用排名工具。该示例应该按照您的要求进行。

DECLARE @Pid TABLE
(
    Id INT,
    PersonId INT,
    Name NVARCHAR(25),
    DisplayOrder INT
)

INSERT INTO @Pid
VALUES
(1 , 10 , 'test1',0 ),
(2 , 10 , 'test2',0 ),
(3 , 10 , 'test3',0 ),
(4 , 10 , 'test4',0 ),
(5 , 10 , 'test5',0 ),
(6 , 11 , 'test6',0 ),
(7 , 11 , 'test7',0 ),
(8 , 12 , 'test8',0 )

UPDATE pid
SET DisplayOrder = dpid.rank
FROM @Pid pid
INNER JOIN 
(
    SELECT *, Rank() OVER(Partition by PersonId Order by Id) as rank
    FROM @Pid
 )dpid ON dpid.Id = pid.Id

 SELECT * 
 FROM @Pid