質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.62%

  • SQL

    2311questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

なぜMAXが必要なのでしょうか

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 153

Hekomi

score 3

 前提・実現したいこと

『達人に学ぶ SQL徹底指南書』でSQLの勉強をし始めたばかりです。
P.23のSQL文で、なぜMAXが必要なのかが理解できず躓いています。

テーブル名:StudentClub
列はstd_id|club_id|club_name|main_club_flgの4列で8行 
std_id|club_id|club_name|main_club_flg
100    1    野球      Y
100    2    吹奏楽     N
200    2    吹奏楽     N
200    3    バドミントン  Y
200    4    サッカー    N
300    4    サッカー    N
400    5    水泳      N
500    6    囲碁      N

・1つだけのクラブに所属している学生については、そのクラブIDを取得する
・複数のクラブをかけ持ちしている学生については、主なクラブのID(main_club_flugがYのクラブ)を取得する

解答は
/* CASE 式の中で集約関数を使う*/
SELECT std_id,
CASE WHEN COUNT(*) = 1 /* 一つのクラブに専念する学生の場合 */
THEN MAX(club_id)
ELSE MAX(CASE WHEN main_club_flg = 'Y'
THEN club_id
ELSE NULL END)
END AS main_club
FROM StudentClub
GROUP BY std_id;

std_id|main_club
100    1
200    3
300    4
400    5
500    6

 発生している問題・エラーメッセージ

SQL文、3行目の「MAX]を外しても出来上がるテーブルに問題はないのですが
4行目の「MAX」を外すと std_id 200 のmain_clubがNULL になるのは何故でしょうか。
そもそも何故、「MAX」が必要なのかが分かりません(>_<)

ご教授いただけないでしょうか。

 該当のソースコード

ソースコード

 試したこと

ここに問題に対して試したことを記載してください。

 補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

はじめまして

そもそも何故、「MAX」が必要なのか

簡単な理由(?)としては

GROUP BY句を使った場合、グループ化した列名以外の
列では集計関数(MAX,MIN, AVG や COUNT(*) など...)が必要
だからです。

GROUP BY句とSQLの集計関数は対で使う、と覚えておきましょう!)

しかし詳細は以下の説明になる、
と思います。
(間違っていたらご指摘ください)


SQLにおけるMAX関数の機能は、少し複雑です。

ttps://www.shift-the-oracle.com/sql/aggregate-functions/max.html
こちらに詳しい説明があります。

抜粋すると

NULL は最大値を選択するためのデータに含まれない。
該当データが無い場合、NULL しかデータが存在しない場合には MAX 関数は NULL を戻す。

だからです。

これだと まずMAXがない状態では

CASE WHEN main_club_flg = 'Y'
THEN club_id
ELSE NULL END
・・・
GROUP BY std_id;

は std_id 200 では
吹奏楽、バドミントン、サッカーの3つなので
[NULL 3 NULL]  =>  NULL
最後のNULLが返ります。

なので 「「MAX」を外すと std_id 200 のmain_clubがNULL」

一方 MAXをつけて

MAX(CASE WHEN main_club_flg = 'Y'
THEN club_id
ELSE NULL END)
・・・
GROUP BY std_id;


を実行すると

まず CASE ~ GROUP BY std_id; は同じなので [NULL 3 NULL] が来て
これをMAX関数で処理するから

MAX([NULL 3 NULL]) => MAXは 3 
(NULL は最大値を選択するためのデータに含まれない。)

std_id 200 のmain_clubは 3 
となります。

こういった解釈だと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/17 07:30

    早速のご回答、本当にありがとうございます!
    朝、既に回答が来ていてビックリしました!!
    超初心者に丁寧に解説してくださり本当に助かります!
    重ね重ね、ありがとうございました!!!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    SQL Server 出力された複数レコードの結果をキー毎に纏めたい

    お世話になります。 SQL Server 2012を使っております。 下記のテーブルに対して、 ◎所属テーブル 部署名 氏名 性別 --------------------

  • 解決済

    MYSQLのCASE分

    select case~~~の部分にelseを書くと思いますが、 elseを取得しない方法はないですか?? 10000件があって caseで金、銀、銅に振り分けて、それ以外は表示

  • 解決済

    【MySQL】月単位での使用件数を表示させたい。

    MySQL 5.5.41を使用しています。 アプリへのアクセスタイプを記録しているテーブル、access_recordがあり、 その表を月単位で(前1年まで)件数を表示させたいと思

  • 解決済

    FROM句のサブクエリについて

    前提・実現したいこと はじめまして、sqlserver 初心者です。 今サブクエリを勉強しているのですが、FROM句だけは別名をつけてJOINしなければならないので難しいです。

  • 解決済

    rails ActiveRecordのselect内で自作メソッドを使う方法はあるか?

    railsでActiveRecordのselect内でstrftimeを使うことができますが、自作したメソッドを使う方法はあるでしょうか? 以下のようにしたらエラーになりました。

  • 解決済

    postgres case trueとfalseが上手く得られない

    以下のSQLでflgが'1'だった場合にtrueをそれ以外に場合にfalseを返すようにしたいのですが。うまくいきません。 結果として帰ってくるのが、'1'だった場合は't'、そ

  • 解決済

    sqlに関してです、

    SUM(CASE WHEN test>=0 && test<=100000 THEN test  ELSE 0 END) AS total, SUM(CASE WHEN test>

  • 受付中

    【SQL】同一のカラムの値で・・・②

    下記の条件でのSQLをなるべくデータベースに掛かるコストが軽くなるように 作成したいのですが、なかなかいい案が思いつきません。  【条件】 抽出結果としては、 下記の条件に当て

同じタグがついた質問を見る

  • SQL

    2311questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。