原谅我,如果这是别人的回答;我有一个工作表,我试图通过查询在MySQL中重新排列。工作表如下所示:
+-------+------+-------+ | Sport |Points| Name | +-------+------+-------+ | A | 53 | Alex | | A | 22 | Jim | | A | 11 | Josh | | B | 63 | Joe | | B | 22 | Rich | | B | 10 | Frank | +-------+------+-------+
我正在寻找一种通过SQL查询以这种格式输出表的有效方法:
+-------+-----+---------+-----+---------+-----+---------+ | Sport | 1st | 1stName | 2nd | 2ndName | 3rd | 3rdName | +-------+-----+---------+-----+---------+-----+---------+ | A | 53 | Alex | 22 | Jim | 11 | Josh | | B | 63 | Joe | 22 | Rich | 10 | Frank | +-------+-----+---------+-----+---------+-----+---------+
通常我不会这样格式化我的桌子,但它让我更容易通过PHP显示每项运动的前3名球员。绝对欢迎任何有效的建议。谢谢!
答案 0 :(得分:1)
首先根据每项运动的得分降序使用变量计算行数。
select sport,points,name,
,@rn:=case when sport=@prev_sport then @rn+1 else @rn end
,@prev_sport:=sport
from t
join (select @rn:=1,@prev_sport:='')
order by sport,points desc
然后使用条件聚合在一行中获得每项运动的前3个分数。
select sport
,max(case when rnum=1 then points end) as p_1
,max(case when rnum=1 then name end) as n_1
,max(case when rnum=2 then points end) as p_2
,max(case when rnum=2 then name end) as n_2
,max(case when rnum=3 then points end) as p_3
,max(case when rnum=3 then name end) as n_3
from (
select sport,points,name
,@rn:=case when sport=@prev_sport then @rn+1 else 1 end as rnum
,@prev_sport:=sport
from t
join (select @rn:=1,@prev_sport:='') r
order by sport,points desc
) x
group by sport
如果有分数关系,则会随意挑选名称。
要断开联系以显示最低或最高名称,可以轻松更改上述查询以包含名称上的排序。
select sport
,max(case when rnum=1 then points end) as p_1
,max(case when rnum=1 then name end) as n_1
,max(case when rnum=2 then points end) as p_2
,max(case when rnum=2 then name end) as n_2
,max(case when rnum=3 then points end) as p_3
,max(case when rnum=3 then name end) as n_3
from (
select sport,points,name
,@rn:=case when sport=@prev_sport then @rn+1 else 1 end as rnum
,@prev_sport:=sport
from t
join (select @rn:=1,@prev_sport:='') r
order by sport,points desc,name --change it to name desc if the highest name should be shown in case of ties
) x
group by sport