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

Reconfiguring table column data in rows via SQL query

如果这是别人回答的,请原谅我;我有一个工作 table 我正在尝试通过查询在 MySQL 中重新排列。工作 table 看起来像这样:

+-------+------+-------+
| Sport |Points| Name  |
+-------+------+-------+
| A     |   53 | Alex  |
| A     |   22 | Jim   |
| A     |   11 | Josh  |
| B     |   63 | Joe   |
| B     |   22 | Rich  |
| B     |   10 | Frank |
+-------+------+-------+

我正在寻找一种通过 sql 查询以这种格式输出 table 的有效方法:

+-------+-----+---------+-----+---------+-----+---------+
| Sport | 1st | 1stName | 2nd | 2ndName | 3rd | 3rdName |
+-------+-----+---------+-----+---------+-----+---------+
| A     |  53 | Alex    |  22 | Jim     |  11 | Josh    |
| B     |  63 | Joe     |  22 | Rich    |  10 | Frank   |
+-------+-----+---------+-----+---------+-----+---------+

通常我不会以这种方式格式化我的 table,但它让我更容易通过 PHP 显示每项运动的前 3 名球员。绝对欢迎任何有效的建议。谢谢!

首先根据每项运动的得分降序使用变量计算行号。

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