• ベストアンサー

集計でテストの各教科の最高得点とその人の名前を取得するには?

お世話になります。 以下のようなデータが収められた、テーブル `test1` から 各教科(subject) の最高得点(score)とその名前(name)を取得したいのですが、 name | subject | score -----+---------+------- 鈴木 | 国語   | 80 山本 | 国語   | 50 佐藤 | 国語   | 90 鈴木 | 英語   | 80 佐藤 | 英語   | 60 山本 | 英語   | 60 鈴木 | 数学   | 50 佐藤 | 数学   | 70 山本 | 数学   | 90 ↓以下の結果取得したい name | subject | score -----+---------+------- 佐藤 | 国語   | 90 鈴木 | 英語   | 80 山本 | 数学   | 90 SELECT `name`,`subject`,MAX(score) AS score FROM `test1` GROUP BY `subject`; のクエリだと以下の結果で期待する結果が取得できません。 name | subject | score -----+---------+------- 鈴木 | 国語   | 90 鈴木 | 数学   | 90 鈴木 | 英語   | 80 どのようにすればいいのでしょうか? 教えていただければ助かります。よろしくお願いします。

  • prorz
  • お礼率100% (3/3)
  • MySQL
  • 回答数3
  • ありがとう数6

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

  • ベストアンサー
  • ESE_SE
  • ベストアンサー率34% (157/458)
回答No.1

まず考え方としては ・各教科ごとの最高点を取得する ・教科と最高点を条件に名前を取得する とすれば良いのではないかと。 当方SQL Server使いなので記法が少々異なるかも知れませんが・・・ SELECT T.name, T.subject, T.score FROM test1 as T INNER JOIN (SELECT subject, MAX(score) FROM test1 GROUP BY subject) as T1 ON T.subject=T1.subject AND T.score=T1.score テーブルT1として教科ごとの最高点を取得、その後テーブルTから 合致する名前を取得します。

prorz
質問者

お礼

ありがとうございます。 期待通りの結果を得ることができました。 ローカルのMySQL5.0の環境では、エラーとなるので MAX(score) → MAX(score) AS score とすることで動作しました。 SELECT T.name, T.subject, T.score FROM test1 as T INNER JOIN (SELECT subject, MAX(score) AS score FROM test1 GROUP BY subject) as T1 ON T.subject=T1.subject AND T.score=T1.score

その他の回答 (2)

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.3

別解です。 select a.* from test1 a inner join ( select subject,max(score) score from test1 group by subject ) b on a.subject=b.subject and a.score=b.score; select a.* from test1 a where not exists ( select 1 from test1 b where a.subject = b.subject and a.score < b.score );

prorz
質問者

お礼

ありがとうございます 期待通りの結果を取得できました。 別解の方法は、なにか他の結果を取得するときにも使えそうですね。 勉強になりました。

回答No.2

RDBMSは、ここのカテゴリ通りMySQLですか? バージョンは? MySQL 4.0以前・・・一部のジョイン、union、一時表などは実装済 MySQL 4.1・・・ジョインの拡張、サブクエリ、unicodeなどの実装。一部の仕様変更。 MySQL 5.0・・・ビュー、ストアドプロシジャ、トリガなどの実装。一部の仕様変更。 MySQLであれば、すぐに思いつくだけでも、上記のような大きな機能追加や仕様変更があります。 >のクエリだと以下の結果で期待する結果が取得できません。 テストデータが良かったということですね。 MySQL 4.1以降で実行可能なSQL例を示します。 select * from test1 as x where score=(select max(score) from test1 where subject=x.subject)

prorz
質問者

お礼

ありがとうございます。 期待通りの結果が得られました。 質問する文章をまとめるので、バージョンを書くのを忘れてました。 テスト環境は、MySQL5.0でした。

関連するQ&A

  • 中間テスト 中1 中1です。初テストがあり、3教科

    中間テスト 中1 中1です。初テストがあり、3教科テスト結果が返ってきました! 国語 平均…69点 自分…82点 英語 平均…75点 自分…88点 社会(地理) 平均…71点 自分…99点(クラストップ) まぁこんな感じなんですが…… どうですか? ちなみに僕の中学には353人1年生がいます。 この点数を計算すると………269点でした! この点数+あとは数学・理科は95点以上はあると思うので、 学年順位は何位ぐらいになると思いますか? みなさん、初めてのテストで予想もつきません。 どれぐらいになるか予想で構いませんので教えてください! ちなみに……… 友達のは……… A君………国語73 理科50 社会59 B君………国語34 英語55 数学37 C君………国語77 英語85 社会69 D君………国語62 英語70 社会83 E君………国語77 英語75 社会73 コイン100枚!!!です。 . この質問に補足する.

  • クエリで複数条件を同時に抽出・出力する方法

    お世話になります。 ACCESSのクエリであるテーブルの入力ミスを抽出したいと考えています。 例えば、氏名と科目と点数があるとします。 No.  氏名  科目  点数 -------------------------- 01 佐藤  国語   80 02 田中  国語   45 03 鈴木  国語   60 04 佐藤  数学   75 05 田中  数学   40 06 鈴木  数学   48 ここで抽出したい条件として、国語は59点以下、数学は49点以下の抽出をしたいとして、今まではクエリの条件に1つずつ科目と点数に条件を入れ1つずつ結果を抽出をしていましたが、同時に結果を得ることができますか?また、結果をリスト表(クエリかレポート)として出力できますか? 拙い文で申し訳ありませんが、分かる方いらっしゃいましたらよろしくお願いいたします。 (スキルとして少しで、ブランクもありますがVBA,SQLです)

  • テスト勉強って教科によって違うけどどんな風にすればいいですか?

    テスト勉強って教科によって違うけどどんな風にすればいいですか? テスト一週間前になったので早起きして、勉強をしているのですが 各教科の勉強をやろうとしても、どんなふうにすればいいかよくわかりません 特に、日本史、古典、英語、ライティング、保険、理科 わかるのが、数学、とにかくレポート用紙に計算しまくる 国語、漢字と教科書を読む 世界史、国語と一緒 理科なんて、赤点ギリギリで勉強法がわかりません 日本史や英語、理科を中心にやり方を教えてください

  • ACCESSでクロス集計風に表示したい

    以下の様なテーブルを 科目 テスト 得点 ------------------ 国語 1中間 50 国語 1期末 60 国語 2中間 55 国語 2期末 65 国語 3期末 70 英語 ・   ・  ・  ・   ・  ・  ・   ・ 数学 1中間 70 数学 1期末 80 数学 3中間 75 数学 2期末 70 数学 3期末 85 以下のような表形式で表示したいと考えてます。    1中間 1期末 ・ ・ 2期末 3期末 国語  60  55  ・ ・  65  70 英語   ・   ・   ・ ・  ・   ・ 数学  70  80  ・ ・  70  85 クロス集計クエリで見た目は上記の表形式になったのですが、 表示されるデータシート?で値の編集が出来ませんでした。 (集計結果なので当然?) 科目及びテストは今後追加される可能性が高いので テーブルまたはフォームを固定で持つことは出来ません。 何か良い方法はないでしょうか?

  • SQL文で

    こんにちは。質問があります。 あるテーブルが以下のようになっているとします。 名前       | 得点 | 科目 ---------------------------------------   山田       | 40 | 国語 加藤       | 60 | 数学 飯塚       | 50 | 数学 加藤       | 45 | 国語 山田       | 80 | 数学 上記のようなテーブルから 名前       | 得点 ---------------------------------------   山田       | 120 加藤       | 105 飯塚       | 50 という結果を取得したいのですが どのようなSQLを書けばいいかわかりません。 宜しくお願いいたします。

  • 定期テストと実力テストの得点差が大きい。勉強方法を教えてください。

    定期テストと実力テストの得点差が大きい。勉強方法を教えてください。 進学高校の1年生です。範囲が限られたで定期テストでは、成績がいいのですが、範囲がない?実力テストでは全く点数がとれません。特に不得意な国語と数学が平均にも行きません。助けて下さい。どなたかいい勉強方法を知っておられる方、またこういう勉強の仕方をしたら成績が上がった方お願いします。ちなみに私は予習復習と宿題を中心に家庭学習をし、週に1回(2時間)の塾に通っています。塾はわからないところを教えて頂くだけです。

  • MySQLで複数のSELECT文を1文にまとめたい

    以下のようなテーブル table1 があります。 ******************* table1 ******************* Name, Kyouka, Score, ID ******************* 山田, 国語, 92, 10001 鈴木, 国語, 71, 10002 田中, 国語, 89, 10003 山田, 数学, 65, 10004 鈴木, 数学, 69, 10005 杉田, 英語, 96, 10006 山田, 英語, 63, 10007 田中, 英語, 76, 10008 ... ******************* カラムIDはPRIMARYを指定しています。 カラムScoreはインデックスを作成しています。 このテーブルで、「IDと教科」を指定したときに、以下の2つのデータを得たいと思っています。 (1) IDに対応する名前と、その教科中の順位 (2) その教科のレコード数 具体例としては、例えば「ID=10001、教科=国語」を指定したときに、「山田、3人中1位」というような情報が得たいです。 (「ID=10001、教科=英語」のようなおかしな組み合わせは指定しないようになっています。) (1) は、以下のようにして名前と順位を得る事が出来ました。 SELECT Name, (SELECT COUNT(*) + 1 FROM table1 b WHERE b.Score > a.Score and Kyouka='国語') AS rank FROM table1 a WHERE ID='10001' ORDER BY Score DESC; (2)は、以下のようにして特定の教科のレコード数を得る事が出来ました。 SELECT COUNT(*) FROM table1 WHERE Kyouka='国語'; しかし、実際にはレコード数が大量にあり、頻繁にこの検索を実行する予定なので、負荷が心配です。 出来るだけサーバーの負荷を減らすために、1回のSELECT文の実行で(1)と(2)をどちらも実現できるような方法はないでしょうか。 また、このテーブルでインデックスを作成しているのはIDとScoreのみですが、より負荷を減らすにはKyoukaにもインデックスを作成した方が良いでしょうか。 何卒、よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • 閲覧ありがとうございます。

    閲覧ありがとうございます。 C言語まったくわからないのですが、2次元配列を用いて c言語で Aさん、Bさん、Cさんの英語、国語、数学、物理のテストの得点を入力し、人毎の合計・平均と科目毎の合計・平均を表形式で出力するプログラムの作成をよろしくお願いいたします。 実行例 学生ごとに試験の得点を入力してください Aさん 英語=74 国語=69 数学=81 物理=72 Bさん 英語=69 国語=77 数学=84 物理=79 Cさん 英語=67 国語=73 数学=69 物理=71 成績集計結果: 英語 国語 数学 物理 合計 平均 Aさん 74 68 81 72 295 73.75 Bさん 69 77 84 79 309 77.25 Cさん 67 73 69 71 280 70.00 合計 210 218 234 222 平均 70.00 72.67 78.00 74.00 このようになるようにお願いいたします。

  • 過去のテスト成績(得点)を呼び出す方法

    毎年、国語と算数の学力テストを行っています。結果が複数のシートに現在の学年が過去の学年で行ったテストの点数が出席番号順に記録されています。 毎年クラス編制替えをしていたり、転出入があるなどで年度ごとに児童の出席番号は変わるので、特定児童の年度別得点推移を確認するのに手間がいります。 そこで、特定の児童名を入力する等簡単な操作で、年度ごとの得点データを呼び出せるような方法はないか模索しています。 エクセルを使用し、できればシンプルな関数などで対応できる方法があればご教授願いたいのですが。 どなたかご存じの方、宜しくお願いします。

  • n人の教科ごとの最高点、最低点を求めるプログラム

    n人の教科ごとの最高点、最低点を求めるプログラム C言語で、タイトルのようなプログラムを作成しています。(n≦100) 教科は国語、数学、英語の3教科です。 作る際の条件として、最高点と最低点を同時に求める関数minmaxを一つだけしか作れません。 入力例) % ./a.out number of persons: 3 Japanese Math English No.1: 90 80 70 No.2: 71 91 81 No.3: 82 72 92 min score: 71 72 70 max score: 90 91 92 現在、構造まで習いました。その知識をもとに以下のようにプログラムしました。(ただ、教科ごとの最高、最低点を求める部分は代表して国語の点の最低点を求める部分だけ載せました) #include <stdio.h> #define MAX 100 struct score{     int jpn;     int math;     int eng; }; void minmax(struct score, int, struct score *, struct score *); main(){     struct score s[MAX], min, max;     int n, i;     printf("number of persons: ");     scanf("%d", &n);     printf("Japanese, Math, English\n");     for (i = 0; i < n; i++) {         printf("No.%d: ", i+1);         scanf("%d %d %d", &(s[i].jpn), &(s[i].math), &(s[i].eng));     }     minmax(s[MAX], n, &min, &max); <------------(☆)     printf("min score: %3d%3d%3d\n", min.jpn, min.math, min.eng);     printf("max score: %3d%3d%3d\n", max.jpn, max.math, max.eng); } void minmax(struct score s[], int n, struct score *minscore, struct score *maxscore) {     int i, max, min;     for (i = 1, min = s[0].jpn; i < n; i++) {         if (min > s[i].jpn) {             min = s[i].jpn;         }     }     minscore->jpn = min; (以下略) } しかし、これをコンパイルすると、 「(☆):パラメータの型1が関数宣言と一致しません。」と出ます。 どこがおかしいのでしょうか、どなたか教えてください。