• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:順位を示すSQLをベースに文字項目の抽出)

kamedaの一番の得意科目(クラスでの相対順位が最上位)は英語で、クラス2位

このQ&Aのポイント
  • 順位を示すSQLをベースに文字項目の抽出
  • MySQL 5.5とCentOS6.3で生徒の成績の得意不得意を表すSQLを考えています
  • kamedaの一番の得意科目(クラスでの相対順位が最上位)は英語で、クラス2位であるということが分かるようにする予定です

質問者が選んだベストアンサー

  • ベストアンサー
  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.1

惜しいところまで行ってるのだけど、1st_kyoka_name= kyoka_name WHERE では、point_rankに存在しないカラム名を指定していることになるので、不可です。 1st_rank をだすときの select 文に kyoka_name カラムを加えたなら、それを from 句にいれて、もう一つ外側に select query を作って、1カラム1行を返すsubqueryを1st_kyoka_nameに代入とする必要があります。 usr_id を指定するには、2つ外となるupdate対象行のカラムを直接指定できないので、t1用のwhere句や order by句 limit句もさらに外側へ出すことになります。 同順のがあると、どちらの教科名になるかは、実行時の運しだい。 select 文で、point_rank と同じカラム構成のデータが作れたら、全カラム一度に insert 可能なので、以下の文で、いけそうです。 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= top_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 ; mysql 5.1 以降なら GROUP_CONCAT() が使えるので、その生徒において、トップとなる教科が複数あれば、カンマで連結して表示するようにしました。 あと、細かいことを言えば、seiseki2のtable で、kyoka_name にindexを付けた方が速くなるのだけど、mysql では、text型にはindex を貼れません。それほど長い文字列が入るとも思えないので、 varchar(20) などで十分では?

tajix14
質問者

お礼

ありがとうございます。 おかげさまで出来ました。 深く御礼申し上げます。 本当にありがとうございました。

その他の回答 (1)

  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.2

済みません、最後に確認せずに、手前カラムのalias 使えたはずと書き換えたら、group関数の結果となるaliasは、次のsubquery d2内で参照出来なかった。 正しくは、以下 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 ;

関連するQ&A