mySQLで学校別の順位を入力する方法

このQ&Aのポイント
  • 東京都の学校別の順位を入力するためには、以下のSQL文を使用することができます。
  • 具体的には、名前、学校、ポイント、ランクの情報が含まれるテーブルに対して、rankカラムとcityカラムを更新する処理を行います。
  • ランクの計算は、ポイントが高い順に並び替えた上で、それぞれの学校ごとに順位を付けます。同点の場合は同じ順位とし、次の順位は1つ飛ばします。
回答を見る
  • ベストアンサー

mySQLでグループ別の順位を入力

東京都の学校別のランクを作っています。 現在、name school pointまでは記載されています。 この後、SQL構文で、rank欄に学校内順位を入れ、city欄にtokyoを入れたいと考えています。 完成形は下記のようなものです。 (同点2位が2人いたら、いずれも2とし、その次の人は4となる) table name__school__city___point___rank kameda__1高__tokyo___345____ 1 suzuki__2高__tokyo___341____ 1 kaneko__3高__tokyo___332____ 1 yosida__2高__tokyo___321____ 2 tanita__1高__tokyo___310____ 2 suyama__1高__tokyo___310____ 2 kisida__2高__tokyo___301____ 3 komine__1高__tokyo___299____ 4 tomita__2高__tokyo___289____ 4 sugita__1高__tokyo___275____ 5 下記のreplace文を考えたのですが、学校別の順位ではなく全体順位の入力となってしまいます。 REPLACE INTO table(rank,city) SELECT ( SELECT COUNT(t2.poit) FROM table t2 WHERE t2.poitn > t1.point AND t2.school = t1.school GROUP BY t2.school ) + 1 AS rank,tokyo FROM table t1; 学校別の順位を入力するためにはどのように改良すればいいでしょうか? SQLはmySQL5.5 CentOS6.3です。 よろしくお願いいたします。

  • MySQL
  • 回答数1
  • ありがとう数1

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

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

元表のプライマリキーはどうなっているのでしょうか? nameをidにするとユニークを確保するのがかなり大変ですが大丈夫ですか? //準備 create table seiseki(name varchar(20) primary key,school varchar(10),city varchar(10) null,point int not null,rank int null); insert into seiseki(name,school,point) values ('kameda','1高',345),('suzuki','2高',341),('kaneko','3高',332),('yosida','2高',321),('tanita','1高',310),('suyama','1高',310),('kisida','2高',301),('komine','1高',299),('tomita','2高',289),('sugita','1高',275); select * from seiseki; //nameごとのschool単位での順位 select name,(select count(*) +1 from seiseki as t2 where 1 and t2.point > t1.point and t2.school= t1.school ) as rank from seiseki as t1; //上を応用して、rankとcityを更新 update seiseki as t0 inner join (select name,(select count(*) +1 from seiseki as t2 where 1 and t2.point > t1.point and t2.school= t1.school ) as rank from seiseki AS t1 ) as t3 on t0.name=t3.name set t0.rank=t3.rank,t0.city='tokyo';

tajix14
質問者

お礼

ご教授いただき有難うございます。 おかげさまで望む形のものを作ることが出来ました ご指摘いただきましたIDについては、別にユーザーIDを別に作り対応することにしました。 本当に有難うございました。

関連するQ&A

  • まったく別のテーブルの結果MYSQL

    table_1 id name age table_2 id book title city day SELECT * FROM table_1 WHERE id=? SELECT book,title FROM table_2 WHERE city=? このようにまったく別のテーブル カラム数も違う WHEREの?も違う これを一つのSQL文にまとめたいのですが。 UNIONなどを使ってもうまくいきませんでした。 ご教授お願いいたします。

    • ベストアンサー
    • MySQL
  • 順位を示すSQLをベースに文字項目の抽出

    生徒の成績の得意不得意をあらわすSQLを考えています。 MySQL 5.5 CentOS6.3 どの教科がその生徒にとって一番得意科目であり、その教科はクラスで何位なのかを示すSQLです。 「クラスでの相対順位のもっとも高い教科とその順位」を表示します。 kamedaの一番の得意科目(クラスでの相対順位が最上位)は英語で、クラス2位である ということが分かるようにする予定です。 一度に名前と順位が入るようにするのが理想なのですが、その方法が分かりませんでしたので、別々にアップデートすることとしました。 アップデートには相対順位がもっとも高い教科を示す【順位SQL】とその教科を表示する【教科SQL】の2つを用意します。 【順位SQL】 「kamedaの一番の得意科目(クラスでの相対順位が最上位)は●●で、クラス2位」を表示する順位SQLは下記のSQLでうまくいきました。 【教科SQL】 次に、●●の部分を埋めるために、教科SQLを組みました。 しかしながら、 #1241 - Operand should contain 1 column(s) になってしまいます。 どこが適切ではないのか、ご教授頂けませんでしょうか? よろしくお願いいたします。 また、もし、2つの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(完成)】 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) 【教科SQL(未完成)】 UPDATE point_rank SET 1st_kyoka_name= kyoka_name WHERE (SELECT kyoka_name,( 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, point_rank AS p1 WHERE t1.usr_id = p1.p_usr_id ORDER BY rank ASC LIMIT 0 , 1) #1241 - Operand should contain 1 column(s)

    • ベストアンサー
    • MySQL
  • 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)

    • ベストアンサー
    • MySQL
  • MySQLから取り出したものを3つに分ける

    MySQLに以下のようなSQLを打ちました。 create table table_list( id int, task varchar(255) ); insert into table_list values(1,'ほげほげ1-1'); insert into table_list values(1,'ほげほげ1-2'); insert into table_list values(2,'ほげほげ2-1); insert into table_list values(2,'ほげほげ2-2'); insert into table_list values(3,'ほげほげ3-1'); そして、空のdiv要素が3つあります。 このデータベースからidの数値別に、div要素へtaskの文字列を入れたいのですが、どうすればいいのでしょうか? SQLで「select * from table_list」をやってからtaskを取り出すのか、3回SQLで「select task from table_list where id=1」のようにするのがよろしいんでしょうか?

    • ベストアンサー
    • PHP
  • 市区町村別の件数をカウントするビュー

    市区町村別の件数をカウントするビューを作りたいのですが、 上手くいきません。 まず、メインの住所が登録されているテーブル(user_table)には 住所とは別に、市区町村名(city)が登録されています。 次にSQL文で create view vUser_table as select city, (select count(*) from user_table where city=x.city) as count from user_table as x と打って、ビューを作成したのですが、 世田谷区 36 中野区 12 足立区 24 世田谷区 36 ・・・・ のように、同じ市区町村が何度もでてきてしまいます。 (件数は同じ) どうすればよいのでしょうか? ご教授ください。

    • ベストアンサー
    • MySQL
  • 同一フィールドの違う値ごとに集計・それぞれ別フィールドに表示したい

    初心者です。 どなたかご教授いただけると助かります。 ===== =table1= usercd point class 1 100 5 2 200 5 1 500 5 3 150 11 =table2= usercd point class 1 150 11 2 700 5 3 200 11 のように、データが2つのテーブルに分かれています。 table1とtable2をUNIONして、usercd ごとの各class の point 合計を表示させたいと思います。 =結果(として期待しているもの)= usercd class5合計 class11合計 1 600 150 2 900 0 3 0 350 ========== UNION して 片方(例:class5) の合計を集計することは出来ました。 =出来たsql= SELECT "usercd",Sum("point") FROM (SELECT * FROM "table1" UNION ALL SELECT * FROM "table2") AS "sumpoint5" WHERE "class" = '5' GROUP BY "usercd"; しかし、それぞれの合計を一度に集計する方法がわかりません。 どうぞよろしくお願いいたします。

  • RANK関数で順位付けする方法

    お世話になります。Oracle初心者です。RANK関数による順位付けについて悩み、検索してもわからず困っております。 次のような表tbがあります。 数値,順 70 10 30 この「順」のカラムに順位を付けて 数値,順 70,3 10,1 30,2 としようとしています。SELECTなら SELECT 数値,rank() over (order by 数値 desc) from tb; が成功します。これでupdateする場合、 (rank() over (order by 数値 desc))をした値を update tb set 順= とすればよいと思うのですが、うまくいきません。 PL/SQLを使わず、SQLでRANK関数を使って順位付けするにはどのようにしたらよろしいでしょうか。 勉強不足だと思い、申し訳なく思います。何卒よろしくお願いいたします。

  • MySQLチューニング

    同順位を考慮したランクの取得について(1~55位まで) 下記の2つのテーブルがあります。 rankingscoreinfo フィールド名 型 長さ missionid integer 4 NOT NULL name varchar 20 NOT NULL skill integer 4 NOT NULL score integer 4 NOT NULL rankinginfo フィールド名 型 長さ NOT NULL missionid integer 4 NOT NULL name varchar 20 NOT NULL kind integer 4 NOT NULL missionidとname2つのテーブルの共通フィールドです。 この二つを組み合わせて同順位を考慮したスコアランキングを作成したいです。 1位のscoreが3人同点の場合、3人のスコアランキングは1位で次の人は4位になるようにしたいです。 SQLを組んだのですがレコード数が増えるにつれてどんどんSQLが返ってくる速度が遅くなって困っています。 この二つのテーブルの最速のSQLを組みたいのですがどなたか教えて下さい。 とりあえずINDEXは考慮なしでお願いします。 参考までに私が組んだSQLは下記のものになります。 SELECT d.name FROM (SELECT *, (SELECT COUNT(a.score)+1 FROM rankingscoreinfo AS a , rankinginfo as b WHERE a.missionid=10 AND a.skill= 2 AND b.kind = 2 AND a.missionid = b.missionid AND a.name = b.name AND a.score > c.score ) AS score_rank FROM rankingscoreinfo AS c WHERE c.missionid = 10 AND c.score AND c.skill=2 ) AS d , rankinginfo as e WHERE e.missionid = 10 AND e.kind = 2 AND d.skill = 2 AND d.missionid = e.missionid AND d.name = e.name AND d.score_rank >=1 AND d.score_rank <= 55 ORDER BY score_rank

    • ベストアンサー
    • MySQL
  • MySQLで検索されたフィールド

    いつもお世話になっております。 MySQLで以下のようなSQL文を発行しています。 select * from table where (INSTR(`table`.`name`,'キーワード')<>0 OR INSTR(`table`.`keyword`,'キーワード')<>0) nameカラムとkeywordカラムのどちらのカラムから検索されたのか知りたいのですが どのようにしたらよろしいでしょうか。 (「キーワード」文字列がどちらのカラムに入っているのか知りたいです。) [環境]  MySQL:5.5.16 よろしくご教示お願いいたします。

    • ベストアンサー
    • MySQL
  • MySQLで現在の順位を取得する方法

    Oracleには、ROWNUMがあるので、 SELECT ROWNUM,id,salary FROM emp order by salary; のように価格(salary)順で順位を振れるので、 そこからSQLだけで現在の順位を取得する事は できるのですが、 MySQLでROWNUMに変わる機能や、 現在の順位を取得する方法はございますでしょうか?