我有一个像这样的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
我想填写rank
和total
值,如下所示:
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
然而,rank
和total
都等于第一个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
所以问题在于更新,它只取第一行并基于它更新所有表。
如何迭代每一行来更新它?
答案 0 :(得分: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;
答案 1 :(得分: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