我有一个users
表,其中包含phase1和phase2列,我需要计算每个阶段的用户排名并将其存储在这些字段中。
排名是根据不同的表points
计算的,其中我有每个用户的逐点数。
我想做的是
users
表及其排名这是我的新表与一些演示数据的外观 sql fiddle demo
目前我使用以下代码来计算我的旧表中的排名,其中排名和用户信息都在同一个表中
update users a
join (
select id,
(
select count(distinct total)
from users d
where c.total < d.total
) +1 rank
from users c
) b on a.id = b.id
set a.rank = b.rank
答案 0 :(得分:1)
oracle中有分析函数,名为rank()和dense_rank(),可用于获取结果。
当你使用mysql时,我试图将这些函数转换为mysql等价物。 您可以使用以下查询获得所需的结果,您可以使用该查询来更新用户表。如果对于成绩也有分数的逻辑,你可能需要进一步改变它。
set @pk1 ='';
set @rn1 =1;
set @tot ='';
set @val =1;
SELECT id,
name,
phase,
phasetotal,
denseRank
FROM
(
SELECT id,
name,
phase,
phasetotal,
@rn1 := if(@pk1=phase, @rn1+@val,1) as denseRank,
@val := if(@pk1=phase, if(@tot=phasetotal, @val+1, 1),1) as value,
@pk1 := phase,
@tot := phasetotal
FROM
(
select users.id,users.name, points.phase, sum(points.points)
as phasetotal from users,points where users.id = points.userid
group by users.id, points.phase order by points.phase, phasetotal desc, points.grade1 desc, points.grade2 desc
) A
) B;
这是更新查询
set @pk1 ='';
set @rn1 =1;
set @tot ='';
set @val =1;
UPDATE users u join (
SELECT id,
name,
phase,
phasetotal,
denseRank
FROM
(
SELECT id,
name,
phase,
phasetotal,
@rn1 := if(@pk1=phase, @rn1+@val,1) as denseRank,
@val := if(@pk1=phase, if(@tot=phasetotal, @val+1, 1),1) as value,
@pk1 := phase,
@tot := phasetotal
FROM
(
select users.id,users.name, points.phase, sum(points.points)
as phasetotal from users,points where users.id = points.userid
group by users.id, points.phase order by points.phase, phasetotal desc, points.grade1 desc, points.grade2 desc
) A
) B ) C on u.id = C.id
SET u.phase1 = CASE WHEN C.phase = 1 and u.phase1 = 0 THEN C.denseRank ELSE u.phase1 END,
u.phase2 = CASE WHEN C.phase = 2 and u.phase2 = 0 THEN C.denseRank ELSE u.phase2 END;