まずカラム同士の比較をするならデータの持ち方がおかしいです。
むりやり処理をするなら一旦ビューをつくるとよいでしょう
SQL
1/* 元データ */
2create table tbl(ID int primary key,name varchar(10),kokugo int,sugaku int,eigo int);
3insert into tbl values
4(1,'佐藤',70,80,85),
5(2,'鈴木',60,90,80),
6(3,'高橋',80,55,95),
7(4,'川島',85,95,70),
8(5,'若林',60,75,90),
9(6,'坂本',90,90,90);
10
11/*ビューの作成*/
12create view v as
13select ID,kyoka,point,(select count(*)+1 from(
14select *,case kyoka when 'kokugo' then 1 when 'sugaku' then 2 else 3 end as sort
15from(
16select ID,'kokugo' as kyoka ,kokugo as point from tbl
17union all select ID,'sugaku',sugaku from tbl
18union all select ID,'eigo',eigo from tbl
19) as t3 )as t4 where t2.ID=t4.ID and (t2.point<t4.point or t2.point=t4.point and t2.sort>t4.sort)) as rank
20 from(
21select *,case kyoka when 'kokugo' then 1 when 'sugaku' then 2 else 3 end as sort
22from(
23select ID,'kokugo' as kyoka ,kokugo as point from tbl
24union all select ID,'sugaku',sugaku from tbl
25union all select ID,'eigo',eigo from tbl
26) as t1 )as t2;
27
28select * from v;
29
ここから上位2個をとりだしますが、順位順にとりだすならjsonデータなどにしないといけません
SQL
1select ID,concat('[',group_concat(concat('{"',kyoka,'"',':',point,',"rank":',rank,'}') order by rank separator ',' ),']')
2as json
3from v
4where rank<=2
5group by ID
結果:
ID | JSON |
---|
1 | [{"eigo":85,"rank":1},{"sugaku":80,"rank":2}] |
2 | [{"sugaku":90,"rank":1},{"eigo":80,"rank":2}] |
3 | [{"eigo":95,"rank":1},{"kokugo":80,"rank":2}] |
4 | [{"sugaku":95,"rank":1},{"kokugo":85,"rank":2}] |
5 | [{"eigo":90,"rank":1},{"sugaku":75,"rank":2}] |
6 | [{"kokugo":90,"rank":1},{"sugaku":90,"rank":2}] |