1

我有一个这样的 sql 表:

表用户

  Id         Name         Country          rank            total
+----+---------------+---------------+-----------------+-------------+
  1          John          Canada                           
  2          Kate          Canada                           
  3          Mark          Canada                           
  4          Max           Argentina                        
  5          Sam           Argentina                        
  6          Stacy         China                            
  7          Ken           China                            
  8          jack          China                            
  9          Don           China                           

我想填写ranktotal值如下:

  Id         Name         Country          rank            total
+----+---------------+---------------+-----------------+-------------+
  1          John          Canada           1                3
  2          Kate          Canada           2                3
  3          Mark          Canada           3                3
  4          Max           Argentina        1                2
  5          Sam           Argentina        2                2
  6          Stacy         China            1                4
  7          Ken           China            2                4
  8          jack          China            3                4
  9          Don           China            4                4

总数基本上是每个国家/地区的总数,排名只是该国家/地区的计数 1,2,3,4....(每个国家都会重置)。

为此,我尝试了以下方法:

update Users
 set rank=u.tempRank, total=u.tempTotal
from
(select *,
         row_number() over (partition by [Country] order by newid()) as tempRank,
         count(*) over (partition by [Country]) as tempTotal
  from Users) as u

然而ranktotal都等于第一个 tempRank 和 tempTotal,我得到了这张表

  Id         Name         Country          rank            total
+----+---------------+---------------+-----------------+-------------+
  1          John          Canada           1                3
  2          Kate          Canada           1                3
  3          Mark          Canada           1                3
  4          Max           Argentina        1                3
  5          Sam           Argentina        1                3
  6          Stacy         China            1                3
  7          Ken           China            1                3
  8          jack          China            1                3
  9          Don           China            1                3

如果我尝试单独调试内部查询:

select *,
         row_number() over (partition by [Country] order by newid()) as tempRank,
         count(*) over (partition by [Country]) as tempTotal
  from Users

无需更新,只需选择,我就会得到正确的结果:

  Id         Name         Country          tempRank        tempTotal
+----+---------------+---------------+-----------------+-------------+
  1          John          Canada           1                3
  2          Kate          Canada           2                3
  3          Mark          Canada           3                3
  4          Max           Argentina        1                2
  5          Sam           Argentina        2                2
  6          Stacy         China            1                4
  7          Ken           China            2                4
  8          jack          China            3                4
  9          Don           China            4                4

所以问题出在更新上,它只取第一行并根据它更新所有表。

如何遍历每一行来更新它?

4

2 回答 2

1

尝试这样做update

with toupdate (
    select *,
           row_number() over (partition by [Country] order by newid()) as tempRank,
           count(*) over (partition by [Country]) as tempTotal
    from Users
   )
update toupdate
   set rank = tempRank, total = tempTotal;

这利用了 SQL Server 的一个非常好的特性,您可以在其中更新和“可更新 CTE”。

您的查询的问题是您有两个未连接的表。我认为您可以将其简化为:

update u
   set rank=u.tempRank, total=u.tempTotal
   from (select *,
                row_number() over (partition by [Country] order by newid()) as tempRank,
                count(*) over (partition by [Country]) as tempTotal
         from Users
        ) u;

否则,您需要将它们连接在一起:

update users
   set rank=u.tempRank, total=u.tempTotal
   from (select *,
                row_number() over (partition by [Country] order by newid()) as tempRank,
                count(*) over (partition by [Country]) as tempTotal
         from Users
        ) u
   where users.id = u.id;
于 2013-11-04T17:28:39.773 回答
0

尝试这个:

Update u set
    rank = (select count(*) from users
            where country = u.country 
               and id <= u.Id),
    total = (Select count(*) from users
             where country = u.country)
From users u
于 2013-11-04T17:30:58.500 回答