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

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

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

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

SQL

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

Q&A

解決済

2回答

11159閲覧

【mySQL】union all の使い方を知りたい

k499778

総合スコア599

MySQL

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

SQL

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

0グッド

0クリップ

投稿2016/08/02 22:43

現在mysqlでデータ取得のコードを書いています。

質問があるのですが、
結論からいうと、

union all で、union all 以降の列にnullがある場合、ASによる別名をつける必要はあるのでしょうか?

例えば以下です。

SQL

1select フルーツ , お菓子 from 料理テーブル where 食べ物フラグ=1 2union all 3select 野菜 , null from 料理テーブル where 食べ物フラグ=2

このようにunion all 以降にnull がある場合、asによる別名を付けなくても良いのでしょうか?
つけたほうが良いのでしょうか?この場合どのように出力されるのでしょうか?

「union all は選択列リストの列数とそれぞれのデータの型が一致していなければいけない」ことは知っているのですが、
細かいルールがわからずにいます。もしわかる方がいればよろしくお願い致します。

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

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

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

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

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

guest

回答2

0

ベストアンサー

UNION ALLで2つのクエリを連結した場合、
原則1つ目のクエリの列名称が採用されます。

つまり、

SQL

1SELECT 2 A.HOGE 3, A.FUGA 4FROM 5 Aテーブル A 6UNION ALL 7SELECT 8 B.COL1 9, NULL 10FROM 11 Bテーブル B

の場合返却される列名は、
HOGE、FUGAとなります。

このようなケースで列別名をつける際は、
HOGE、FUGA側の方で列別名を指定すると良いでしょう。

###追記
カラム数が異常に多かったり、
擬似的に作成したNULLを返すカラムが多いケースでは、
可読性、保守性の観点から列別名を明示するのは有用です。

前のサンプルを使うと以下のイメージ

SQL

1SELECT 2 A.HOGE AS "ヤック" 3, A.FUGA AS "デカルチャー" 4FROM 5 Aテーブル A 6UNION ALL 7SELECT 8 B.COL1 AS "ヤック" 9, NULL AS "デカルチャー" 10FROM 11 Bテーブル B

ちなみにUNION ALL以外も、
UNION、EXCEPT(OracleはMINUS)、INTERSECTなどの、
集合演算子の列名については全て同じような振る舞いとなります。

###集合演算子利用時の列別名利用について
コメントが長くなりそうだったのでこちらで。

まだまだ半人前の僕の短い経験上ですが、
UNIONなどの集合演算子を利用するシーンで、
後者(2つ目)のクエリにのみ別名をつけるケースは、
あまり見かけた覚えがありません(もしかしたら普通によく使われてるかも)。

パターンとしては以下の3パターンが多い気がします。
0. 前者のクエリだけ別名を明示する
0. 前者、後者ともに別名を明示する
0. そもそも別名を付けない

1つ目のパターンは、
そもそも1つ目のカラム名に合わせて結果セットの列名が決まるのだから、
2つ目の別名指定は冗長という考え方に基づくと思われます。

2つ目のパターンは、
いやいやぱっと見で前者と後者の対応が分からないのはけしからんでしょとか、
後から修正する際にカラム名揃ってないとエディタのキーワード検索で引っかからないじゃんとか、
可読性と保守性を重視した考え方に基づくと思います。

3つ目のパターンは、
1つ目のクエリのテーブル列名から一切変える必要もないので、
わざわざ記載するだけ冗長という考え方に基づくと思われます。

特に多いのは1つ目、2つ目の書き方だと思うのですが、
その理由としてはそもそもUNIONなどの集合演算子の性質とか利用目的を考えてもらうと分かるかもしれません。

UNIONなどでレコードをくっつけるケースというのは、
テーブルは異なるけど構造などが共通しているものを、
まとめて取得したいという目的が多いと思います。

こう例えると誤りもあるかもですが、
UNIONで束ねて取得することは、
オブジェクト指向でいう所の、
特化(派生クラス)・汎化(基底クラス)の関係を再現しているとも言える部分があります。

例えばサンプルして掲示されたSQLでは、
野菜、フルーツ、お菓子というテーブルというか、
食べ物区分による分類がありますよね。

これらをUNIONで束ねて名称を取得したい場合、
列別名を指定しないとカラム名が野菜名となってるのにもかかわらず、
その中にはフルーツ名・お菓子名も入ってますという事態になります。

そこでUNIONで束ねたものは、
名称については野菜名じゃなく別名で食物名にしましょうとか、
より一般化した列別名を付けることが多いです。
(元々全部のカラムがNAMEとかだったら汎化しようにないですがw)

そういった事情もあり、
上記1つ目、2つ目の別名の振り方が多いのかなと個人的には思ってます。
(テーブル設計でも実はスーパタイプ、サブタイプというオブジェクト指向的な切り口の考え方がありますが、
蛇足が過ぎるので割愛します。)

……と長々と語りはしましたが、
結局は列別名の振り方とかも個人の好みの問題の側面が強いのでご自身がやりやすいように、
そして他の方が後々メンテナンスする際に分かりにくくならないように、
上記を意識して取り組むと他者が見てケチが付けられにくいコーディングが出来るようになってくるでしょう。

僕自身も修行中の身ではありますので、偉そうにし過ぎ感MAXですが。

投稿2016/08/02 23:19

編集2016/08/03 13:09
Panzer_vor

総合スコア1636

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

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

k499778

2016/08/02 23:22

回答ありがとうございます。 なるほど。勉強になります。 原則union all 以降のクエリにはわざわざasで1つ目のクエリ名をつけるようなことはしなくてもいいのでしょうか?
Panzer_vor

2016/08/02 23:26 編集

カラム数が多い場合や、 可読性に不安がある場合などにあえて両方のクエリに列別名を指定するというケースはあり得ます。 ただクエリの動作的には、 UNION ALLの後のクエリの列別名は採用されないという点には注意すればよろしいかと
k499778

2016/08/03 11:03 編集

回答ありがとうございます。 すごく理解できました。 最後に1つだけお伺いしたいのですが、 union allの1つ目のクエリに名前を合わせる場合、2つ目のクエリのnullにだけasで1つ目のクエリの該当する列名をつけるというのは変でしょうか?1つ目のクエリにはasをつけずに。 1つ目のクエリに名前を合わせるため、1つ目にasをつけるのは冗長なので2つ目だけにつけるのはどうかなと思いました。
Panzer_vor

2016/08/03 12:10

2つ目のクエリのNULLの個所だけ別名を付けるというのは個人的には少し違和感があります。 そうするのであれば2つ目のクエリには取得カラム全てに別名を明示した方が個人的には良い気がします。 まぁ列別名付ける付けない周りは個人な好き好きもあるのであくまで個人的な意見ですが…w 集合演算子で利用時の列別名について少し回答追記しときます。
k499778

2016/08/03 13:06

回答ありがとうございます。 やはり違和感ありますか(^^;; 回答追記ありがとうございます。勉強させていただきます。
guest

0

結局このやり方にするならUNIONしなくても

SQL

1select 2case 食べ物フラグ 3when 1 then 野菜 4when 2 then フルーツ 5end as カラム1 6,case 食べ物フラグ 7when 1 then null 8when 2 then お菓子 9end as カラム2 10from 料理テーブル where 食べ物フラグ in (1,2);

とすればよいのでは?
(食べ物フラグが以前いわれたのと逆なような気がしたので逆転してあります)

投稿2016/08/03 00:20

yambejp

総合スコア114572

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

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

asahina_dev

2016/08/03 03:21

それ 前スレで提案した
k499778

2016/08/03 11:02 編集

回答ありがとうございます。 SQLは前のを引用して使っているのですが、今回はnullに対するasをつけるかどうかという部分にのみフィーチャーした質問でした。 このクエリはあくまで例えであって実際のクエリは内容がもっと濃いものとなっているのです。 回答していただき感謝しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問