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

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

新規登録して質問してみよう
ただいま回答率
85.35%
GROUP BY

GROUP BYとはSQL文のひとつで、SELECT文において特定の列の値が等しい行ごとに表をグループ化します。

SQL

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

Q&A

解決済

1回答

8548閲覧

GROUP BYしたレコードにて優先順位が高い項目を取り出すSQLの作成方法

piyopiyo_pi

総合スコア6

GROUP BY

GROUP BYとはSQL文のひとつで、SELECT文において特定の列の値が等しい行ごとに表をグループ化します。

SQL

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

0グッド

0クリップ

投稿2020/02/20 12:36

前提・実現したいこと

重複した値を持つ複数のレコードを一つにまとめて見やすく成型するSQLを考えています。
GROUP BYしたレコードにて判定分を書いているのですが、
複数項目があてはまる場合は優先順位が高いほうを項目として取り出したいと考えています。

例)
★「生徒名簿」上のレコード
生徒ID|学年|年度|クラブID|優先順位|…
0001| 1|2019| 1| 1|…
0001| 1|2019| 2| 2|…
0001| 2|2020| 2| 1|…

★「クラブ名簿」上のレコード
クラブID|クラブ名|…
1| 水泳|…
2| 手芸|…

★「クラブ履歴」
生徒ID|2019_所属クラブ|2020_所属クラブ|…
0001| 水泳| 手芸|…

上記の例では、生徒名簿とクラブ名簿というテーブルを、クラブ履歴というテーブルにまとめてみれるようにしたいのです。

試したこと

自力で途中まで書いたSQL↓

select
生徒名簿.生徒ID as 生徒ID
MAX(CASE 生徒名簿.年度 WHEN '2019' THEN クラブ名簿.クラブ名 ELSE NULL END) AS 2019_所属クラブ,
MAX(CASE 生徒名簿.年度 WHEN '2020' THEN クラブ名簿.クラブ名 ELSE NULL END) AS 2020_所属クラブ

FROM 生徒名簿
INNER JOIN クラブ名簿
ON 生徒名簿.クラブID = クラブ名簿.クラブID

GROUP BY 生徒名簿.生徒ID

ここまでは検索して、自力で書くことができましたが、優先順位による判定を、どこに入れ込めばよいかがわからず、困っています。

初歩的な質問で非常に恐縮なのですが、周りに頼れる人がいないため、こちらにて相談させていただきました。
お知恵を貸していただけますと幸いです。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Orlofsky

2020/02/20 12:56

同じSQLでもデータベースやそのバージョンによって方言が大きいですから、どのデータベースを使うのかを質問のタグで示したり、バージョンも明記した方が適切なコメントが付き易いです。
piyopiyo_pi

2020/02/20 16:36

拙い質問に目を通してくださりありがとうございます。 Spark SQLを使用しております。バージョンは後程追記いたします。
guest

回答1

0

ベストアンサー

こんな感じだと思います。

SQL

1select 生徒ID 2 , Max(CASE 年度 WHEN '2019' THEN クラブ名 END) AS 2019_所属クラブ 3 , Max(CASE 年度 WHEN '2020' THEN クラブ名 END) AS 2020_所属クラブ 4FROM 生徒名簿 t1 INNER JOIN クラブ名簿 t2 5 ON t1.クラブID = t2.クラブID 6where 優先度 = ( 7 select Min(優先度) from 生徒名簿 where 生徒ID=t1.生徒ID and 年度=t1.年度 8 ) 9group by 生徒ID

尚、正規化はされた方が良いかと思います。
今のデータから正規化されてテーブルを作るのは例えば以下のようにします。

SQL

1create table 所属クラブ as 2select 生徒ID, 年度, クラブID, 優先順位 3from 生徒名簿

SQL

1create table 生徒名簿_改 as 2select 生徒ID, 学年, 年度 3from 生徒名簿 4group by 生徒ID, 学年, 年度

投稿2020/02/20 16:20

sazi

総合スコア25327

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

piyopiyo_pi

2020/02/20 16:53

投稿してすぐにご回答いただけて驚きました。 そしてとてもわかりやすい回答をありがとうございました。 正規化についてもご説明くださりありがとうございます。お恥ずかしい話ですが、全く考慮していなかったので、とても勉強になりました。 感謝の言葉しかございません。早速確認してみます。本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問