通过SQL查询重新配置行中的表列数据

时间:2017-03-21 23:12:31

标签: mysql sql pivot

原谅我,如果这是别人的回答;我有一个工作表,我试图通过查询在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名球员。绝对欢迎任何有效的建议。谢谢!

1 个答案:

答案 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