min句のSQLを改造し二番目に小さいdata抽出
2度目の質問となり恐縮しております。
生徒の成績の得意不得意をあらわすSQLを考えています。(mySQL 5.5 centOS6.3)
テストの成績をもとに
「kamedaの一番の得意科目(クラスでの相対順位が最上位)は英語で、クラス2位である」
「kamedaの二番の得意科目は数学で、クラス4位である」
「kamedaの三番の得意科目は国語で、クラス7位である」
ということが分かるようにする予定です。
当初私が考えた案ではlimit句を使った方法を考えており、limit後の値を変更することにより2位、3位を出す予定でしたが、私の方法ではうまくいかなかったためこのサイトで質問をさせて頂いたところ、minを使った方法を紹介れました。
(私の質問方法が「クラスの最上位を求める」というように省略して記載していたためmin句での回答を頂くことになりました)
この回答をベースに当方で2番目を抽出出来るよう改造に着手しましたがうまく出来ません。
●min句ベースではminから2番目というものをどうしても取ることが出来ませんでした。
●このmin句ベースのものをlimit句のSQLに改造しようとトライしたのですがどうしても改造することが出来ませんでした。
何度もこの場をお借りして恐縮ですがお知恵を拝借したくお願い申し上げます。
****************************************************
ベースとなるデータ
CREATE table seiseki2
(usr_id TEXT,kyoka_name TEXT,point INT);
CREATE table point_rank
(p_usr_id TEXT,1st_kyoka_name TEXT,1st_rank INT);
INSERT INTO seiseki2
(usr_id,kyoka_name,point)
values
('kameda','数学',85),('suzuki','数学',71),('kaneko','数学',32),('yosida','数学',61),('tanita','数学',70),('suyama','数学',80),('kisida','数学',61),('komine','数学',99),('tomita','数学',89),('sugita','数学',75),('kameda','国語',80),('suzuki','国語',46),('kaneko','国語',52),('yosida','国語',89),('tanita','国語',77),('suyama','国語',67),('kisida','国語',81),('komine','国語',89),('tomita','国語',69),('sugita','国語',70),('kameda','英語',94),('suzuki','英語',86),('kaneko','英語',50),('yosida','英語',59),('tanita','英語',48),('suyama','英語',97),('kisida','英語',74),('komine','英語',82),('tomita','英語',59),('sugita','英語',60);
INSERT INTO point_rank
(p_usr_id,1st_kyoka_name,1st_rank)
values
('kameda','',''),('suzuki','',''),('kaneko','',''),('yosida','',''),('tanita','',''),('suyama','',''),('kisida','',''),('komine','',''),('tomita','',''),('sugita','','');
*****************************************************
この場で回答頂きましたSQL
下記はmin句を使用して最上位の教科を出すことが出来ます。
今回の質問は下記を改良し、2番目の教科、3番目の教科を出したいと考えています
INSERT INTO point_rank (p_usr_id, 1st_rank, 1st_kyoka_name )
SELECT d1.id
, min(d1.rank) AS top_rank
, (select GROUP_CONCAT( kyoka )
from (SELECT t1.usr_id as id , t1.kyoka_name as kyoka
,( SELECT count( * ) +1
FROM seiseki2 AS t2
WHERE t2.point > t1.point AND t2.kyoka_name = t1.kyoka_name
) AS rank
FROM seiseki2 AS t1
) as d2
where d2.id=d1.id and d2.rank= min(d1.rank)
group by d2.id
) AS kyoka
FROM ( select t1.usr_id as id
,( SELECT count( * ) +1
FROM seiseki2 AS t2
WHERE t2.point > t1.point AND t2.kyoka_name = t1.kyoka_name
) AS rank
FROM seiseki2 AS t1
) as d1
group by d1.id
;
*********************************************
ご参考
私が当初考えたSQL 順位は出ますが教科が出せません
UPDATE point_rank
SET
1st_rank=
(SELECT (
SELECT count( * ) +1
FROM seiseki2 AS t2
WHERE 1
AND t2.point > t1.point
AND t2.kyoka_name = t1.kyoka_name
) AS rank
FROM seiseki2 AS t1
WHERE t1.usr_id = point_rank.p_usr_id
ORDER BY rank ASC
LIMIT 0 , 1)