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

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

ただいまの
回答率

90.50%

  • MySQL

    7005questions

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

  • SQL

    3017questions

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

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

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 5,093

k499778

score 513

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

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

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

例えば以下です。

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

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

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

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+3

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

つまり、

SELECT
    A.HOGE
,   A.FUGA
FROM
    Aテーブル A
UNION ALL
SELECT
    B.COL1
,   NULL
FROM
    Bテーブル B


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

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

追記

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

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

SELECT
    A.HOGE AS "ヤック"
,   A.FUGA AS "デカルチャー"
FROM
    Aテーブル A
UNION ALL
SELECT
    B.COL1 AS "ヤック"
,   NULL AS "デカルチャー"
FROM
    Bテーブル B

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

集合演算子利用時の列別名利用について

コメントが長くなりそうだったのでこちらで。

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

パターンとしては以下の3パターンが多い気がします。

  1. 前者のクエリだけ別名を明示する
  2. 前者、後者ともに別名を明示する
  3. そもそも別名を付けない

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

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

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

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

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

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

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

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

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

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

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

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

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/08/03 08:22

    回答ありがとうございます。
    なるほど。勉強になります。

    原則union all 以降のクエリにはわざわざasで1つ目のクエリ名をつけるようなことはしなくてもいいのでしょうか?

    キャンセル

  • 2016/08/03 08:25 編集

    カラム数が多い場合や、
    可読性に不安がある場合などにあえて両方のクエリに列別名を指定するというケースはあり得ます。

    ただクエリの動作的には、
    UNION ALLの後のクエリの列別名は採用されないという点には注意すればよろしいかと

    キャンセル

  • 2016/08/03 19:57 編集

    回答ありがとうございます。

    すごく理解できました。

    最後に1つだけお伺いしたいのですが、
    union allの1つ目のクエリに名前を合わせる場合、2つ目のクエリのnullにだけasで1つ目のクエリの該当する列名をつけるというのは変でしょうか?1つ目のクエリにはasをつけずに。

    1つ目のクエリに名前を合わせるため、1つ目にasをつけるのは冗長なので2つ目だけにつけるのはどうかなと思いました。

    キャンセル

  • 2016/08/03 21:10

    2つ目のクエリのNULLの個所だけ別名を付けるというのは個人的には少し違和感があります。
    そうするのであれば2つ目のクエリには取得カラム全てに別名を明示した方が個人的には良い気がします。

    まぁ列別名付ける付けない周りは個人な好き好きもあるのであくまで個人的な意見ですが…w

    集合演算子で利用時の列別名について少し回答追記しときます。

    キャンセル

  • 2016/08/03 22:06

    回答ありがとうございます。

    やはり違和感ありますか(^^;;

    回答追記ありがとうございます。勉強させていただきます。

    キャンセル

+1

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

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


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

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/08/03 12:21

    それ 前スレで提案した

    キャンセル

  • 2016/08/03 19:59 編集

    回答ありがとうございます。

    SQLは前のを引用して使っているのですが、今回はnullに対するasをつけるかどうかという部分にのみフィーチャーした質問でした。

    このクエリはあくまで例えであって実際のクエリは内容がもっと濃いものとなっているのです。

    回答していただき感謝しています。

    キャンセル

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

  • MySQL

    7005questions

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

  • SQL

    3017questions

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