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

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

新規登録して質問してみよう
ただいま回答率
85.51%
VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

SQL

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

Q&A

解決済

4回答

1734閲覧

同じ条件を持つ場合の表を作るときの考え方

10morokoshi

総合スコア14

VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

SQL

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

0グッド

0クリップ

投稿2017/07/05 07:23

編集2017/07/05 08:46

連日の質問失礼いたします。知恵をお貸しいただけると幸いです。
Visual Studio2015で開発しております。

まず、データベース(phpMyAdmin使用)には以下のテーブルがあります。
イメージ説明
そして、下図のように表の出力をしたいです。
イメージ説明

こういった結果を得ることはできるのですが、(SQLでINNERJOIN結合したものを取得して、クラスにためたあと、ディクショナリーに加える)↓
イメージ説明
身長を横に並べるのにはどうしたらいいかわかりません。
先日投稿した質問にいただいた回答を参考にpivotなどを調べ、試してみましたが、思うようにいかなかったため、SQLで解決しようとするのが違うのかなという結論に至りました。
最終的に帳票として出力します。最後の図のようなものであれば出力することはできています。

これを解決するには、どのようなコード、考え方をすればよいのでしょうか…。パソコン、プログラミングなどの知識が全くない状態から始めて3カ月ほどなのですが、未だに考え方に柔軟な対応ができず…。

ご回答お願いいたします。

--追記です

詳細を書かせていただきます。
取得したいのは去年と今年だけで、データベースに保存されている年度は2016/01/01というような日付は1月1日固定で、年だけが違う日付型で登録されています。
motuo様が書いてくださったSQLの max(CASE WHEN tableb.year = 2016 then tableb.sintyo END)などの年度を指定しているところにはその日付を予めプログラムで取得しており、それを入れるようにしたので、そこは変数に変更しています。Addyear(-1)で去年分も出しています。
もっと言うと、検索条件は出席番号A1番からB31番まで、ですとか、欲しいテーブルは去年の身長と今年の身長、今年の委員会など、去年のはいらないけれど、今年のは欲しいという値も存在するのですが、それはいただいた回答を応用することで解決するかなと思ったので書きませんでした。
このプログラムで更新ですとかそういったことをすることはなくて、ただそのときに欲しい範囲の表を出力するだけです。
稚拙な文章ですみません。追記の指摘やご回答いただけると幸いです。

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

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

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

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

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

mattn

2017/07/05 08:09

10morokoshi さん、そろそろお気付きかもしれませんが、この年毎に増えるテーブルを横列にするという事は、来年新しく身長を登録するとこの SQL も改変する必要があります。例えば去年と今年の分だけを表にしたいといった場合はプログラムを書いたり、バッチ処理という手続きが必要になります。かたやプログラムで作る場合ですと、SQL を組み立てる際に去年(2016)と今年(2017)という数字を得て文字列結合するといった事で毎年 SQL を改変しなくても良くなります。 やろうとされておられる内容や、要望(毎年更新したくない)等により回答内容が異なりますので、もう少し詳細を説明下さい。
10morokoshi

2017/07/05 08:36

ありがとうございます。追記いたしました。
guest

回答4

0

考え方だけ。
やり方はたくさんあります。が基本的に
1.「こんなテーブルが存在したら簡単にできる」とういう状態を考える
2.サブクエリと集計関数でほしい"こんなテーブル"の形を作る
3.2て作った形を1に代入する。
と考えると考えやすい。
部品をつくって組み上げていくという意味では普通の手続き型プログラムと考え方は同じです。
通常のプログラムがモジュールを作って組み上げていくのにたいし、SQLはサブクエリ等"部分集合"をつくって組み上げる。
方法その1:
テーブルBが20016年と20017年で別だったら?と考える
テーブルBがテーブルB_2016、テーブルB_2017という2テーブルだったら簡単。ただの結合です。

SQL

1//テーブルB_2016、テーブルB_2017があれば動くSQL 2SELECT a.出席番号, a.名前, b1.身長 AS 身長2016, b2.身長 AS 身長2017 3FROM テーブルA a 4LEFT JOIN テーブルB_2016 b1 ON b1.ID = a.ID 5LEFT JOIN テーブルB_2017 b2 ON b2.ID = a.ID

ここまで作ってテーブルB_2016、テーブルB_2017をサブクエリで作れば良い。

SQL

1//テーブルB_2016と同じ 2SELECT ID,身長 FROM テーブルB WHERE=2016 3//テーブルB_2017と同じ 4SELECT ID,身長 FROM テーブルB WHERE=2017

これを置き換えればできあがり

SQL

1//完成 2SELECT a.出席番号, a.名前, b1.身長 AS 身長2016, b2.身長 AS 身長2017 3FROM テーブルA a 4LEFT JOIN (SELECT ID,身長 FROM テーブルB WHERE=2016) b1 ON b1.ID = a.ID 5LEFT JOIN (SELECT ID,身長 FROM テーブルB WHERE=2017) b2 ON b2.ID = a.ID

方法その2:
こんなテーブルがあると楽。
テーブルX

ID身長2016身長2017
1150151
2142145

これなら

SQL

1//テーブルXがあれば動く 2SELECT a.出席番号, a.名前, x.身長2016, x.身長2017 3FROM テーブルA a 4LEFT JOIN テーブルX x ON x.ID = a.ID

でできる。テーブルXはどうすればできるかかんがえると、こんなテーブルがあれば良い。
テーブルY

ID身長2016身長2017
120161500
120170151
220161420
220170145

テーブルXはテーブルYがあれば

SQL

1//テーブルYからテーブルXをつくる 2SELECT ID,SUM(身長2016) AS 身長2016,SUM(身長2017) AS 身長2017 FROM テーブルY GROUP BY ID 3または 4SELECT ID,MAX(身長2016) AS 身長2016,MAX(身長2017) AS 身長2017 FROM テーブルY GROUP BY ID

でできる。で、テーブルYはテーブルBをつかって

SQL

1//テーブルBからテーブルYをつくる 2SELECT 3ID, 4CASE WHEN=2016 THEN 身長 ELSE 0 END AS 身長2016, 5CASE WHEN=2017 THEN 身長 ELSE 0 END AS 身長2017 6FROM テーブルB

でできる。これを最初のSQLに代入すれば

SQL

1//完成(改良前) 2SELECT a.出席番号, a.名前, x.身長2016, x.身長2017 3FROM テーブルA a 4LEFT JOIN 5(SELECT ID, 6MAX(身長2016) AS 身長2016, 7MAX(身長2017) AS 身長2017 FROM 8(SELECT 9ID, 10CASE WHEN=2016 THEN 身長 ELSE 0 END AS 身長2016, 11CASE WHEN=2017 THEN 身長 ELSE 0 END AS 身長2017 12FROM テーブルB) y GROUP BY ID) x ON x.ID = a.ID

これでも動くが、X,Yはまとめられるので

SQL

1//完成 2SELECT a.出席番号, a.名前, x.身長2016, x.身長2017 3FROM テーブルA a 4LEFT JOIN 5(SELECT ID, 6MAX(CASE WHEN=2016 THEN 身長 ELSE 0 END) AS 身長2016, 7MAX(CASE WHEN=2017 THEN 身長 ELSE 0 END) AS 身長2017 8FROM テーブルB GROUP BY ID) x ON x.ID = a.ID

性能とか考えるとまた別の話も必要ですが、とりあえずわりと汎用性の高い考え方の一つ。

投稿2017/07/05 11:41

編集2017/07/05 11:46
kurokoba

総合スコア276

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

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

10morokoshi

2017/07/06 07:30

ありがとうございます、考え方という点でとても助かりました。
guest

0

ベストアンサー

すいません。前回の質問とほぼ同じ内容に見えるのですが…
まず、下記のSQLで欲しい表を取得する事が出来ると思います。

SQL

1Select 2 shussekiNo, 3 name, 4 max(CASE WHEN tableb.year = 2016 then tableb.sintyo END) as sintyo2016, 5 max(case when tableb.year = 2017 then tableb.sintyo END) as sintyo2017 6From 7 tablea 8Left Outer Join tableb 9 on tablea.ID = tableb.id 10Group by 11 tablea.shussekiNo

結果
イメージ説明

前回の質問でわからなかった部分を、もう少し具体的に書くと、違った観点からアドバイスできるかも
しれません。

去年と今年を実行日で判定するSQL

SQL

1Select 2 shussekiNo, 3 name, 4 max(CASE WHEN tableb.year = YEAR(CURDATE()) - 1 then tableb.sintyo END) as lastYear, 5 max(case when tableb.year = YEAR(CURDATE()) then tableb.sintyo END) as currentYear 6From 7 tablea 8Left Outer Join tableb 9 on tablea.ID = tableb.id 10Group by 11 tablea.shussekiNo

投稿2017/07/05 07:51

編集2017/07/05 08:46
motuo

総合スコア3027

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

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

10morokoshi

2017/07/05 08:37

ありがとうございます。思う結果が出ました。私の理解力がなかったようです…。前回回答してくださった方も含め、申し訳ございません。
motuo

2017/07/05 08:45

あと、今年と去年は変数で与えても良いですが、 YEAR(CURDATE())で今年を取得する事が出来ます。(年度になるとちょっと面倒ですが…) ついでなので追記しておきます。
10morokoshi

2017/07/05 08:50

ご丁寧にありがとうございます。年度に関しては、仕様上決まっているためこれを使用しております。今後使う知識として、参考にさせていただきます!
motuo

2017/07/05 08:59

知りたいことに対する回答は上記で十分でしょうか?(この件ではもう詰まっていませんか?) 十分であれば良いのですが、追記を見ても最終的に何を知りたいか私には読み切れず…
10morokoshi

2017/07/05 09:02

はい、おかげ様でだいたい解決したように思います。しかし、本格的に試すのが明日になってしまうため、mattan様の回答も待ちつつ、解決済にするのは後日にしようと思います。
guest

0

それぞれJOINしてはどうでしょうか?

SQL

1SELECT A.出席番号, A.名前, B2016.身長 身長2016, B2017.身長 身長2017 2FROM A 3INNER JOIN B B2016 ON B2016.ID = A.ID AND B2016.= 2016 4INNER JOIN B B2017 ON B2017.ID = A.ID AND B2017.= 2017

投稿2017/07/05 07:48

x_x

総合スコア13749

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

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

10morokoshi

2017/07/05 08:38

ありがとうございます。参考にさせていただきます。
guest

0

前回の回答のとおりだと思いますが、どこがつまっているのでしょうか?

投稿2017/07/05 07:46

yambejp

総合スコア114505

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

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

10morokoshi

2017/07/05 08:52

私の理解力の無さが問題でした、申し訳ございません。おおよそは解決したと思います。しかし、他の問題にぶつかりそうですので、他の方の回答を参考にしたうえでさらに追記させていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問