【PostgreSQL】ポケモンずかんをつくってSQLを学ぶ5（SELECTの復習・UNION）

##はじめに
この記事はPostgreSQLの勉強のアウトプットにポケモンずかんをつくりながら学びを深める試みです。
作業環境はpgAdminで行っています。

####過去の記事
現在までの操作を記事化してたら謎のシリーズ化し始めてます。

- [【PostgreSQL】ポケモンずかんをつくってSQLを学ぶ1（テーブルを作成）](https://qiita.com/takahirocook/items/2f5cba7db434280c5702)
- [【PostgreSQL】ポケモンずかんをつくってSQLを学ぶ2（データの登録・変更）](https://qiita.com/takahirocook/items/29945efdb41e030874eb)
- [【PostgreSQL】ポケモンずかんをつくってSQLを学ぶ3（データを取り出す）](https://qiita.com/takahirocook/items/89aba8585dcd42dd310f)
- [【PostgreSQL】ポケモンずかんをつくってSQLを学ぶ4（レコードの更新・削除）
](https://qiita.com/takahirocook/items/b6f56c1c064a74d9b1ae)
- **→ 現在の記事はここです**

楽しくSQLの理解を深めることが一番の目的なため、登録される順序などは実際のポケモン図鑑の内容と違う部分があるかとおもいますが、そこは全力を上げて見逃していただけると嬉しいです。
また、SQL初学者のため謎の動きもするかとおもいますが、それらの生々しい修正作業なども記録しながら作成していきますので、時々寄り道をしながら理解をより深めていきたいと思いますので、よろしくお願いします。

##学習の準備

###ポケモンの追加
新しくつかまえたポケモンを追加したいと思います。[前回の記事](https://qiita.com/takahirocook/items/29945efdb41e030874eb#comment-bae8216b5db36cc1b624)でレビューをしていただいた方から、**SELECT結果をINSERTする**やりかたを教えていただきました。（@dodonki1223 さん、ありがとうございます！）
今まで使ってきた**`VALUE`**宣言をしてから値を割り振るのではなく、UNIONをつかって複数のSELECT結果を登録しています。
まずは早速使ってみます。

```SQL
INSERT INTO pokedex_kanto
          SELECT 24 AS number, 'アーボック'   AS name, 'コブラポケモン' AS category, 'どく' AS type1, '' AS type2, 3.5 AS height, 65.0 AS weight, 'おなかの　もようが　こわいかおにみえる。　よわいてきは　そのもようをみただけで　にげだして　しまう。'      AS description, current_timestamp
UNION ALL SELECT 26 AS number, 'ライチュウ'   AS name, 'ねずみポケモン' AS category, 'でんき'   AS type1, '' AS type2, 0.8 AS height, 30.0 AS weight, 'ながい　しっぽが　アースになって　みを　まもるため　じぶんじしんは　こうでんあつにも　しびれないのだ。'     AS description, current_timestamp
UNION ALL SELECT 27 AS number, 'サンド' AS name, 'ねずみポケモン'   AS category, 'じめん' AS type1, '' AS type2, 0.6 AS height, 12.0 AS weight, 'かんそうした　すなちで　すなあびを　するのが　すき。　からだに　ついた　よごれと　みずけを　おとすのだ。' AS description, current_timestamp
UNION ALL SELECT 28 AS number, 'サンドパン' AS name, 'ねずみポケモン'   AS category, 'じめん' AS type1, '' AS type2, 1.0 AS height, 29.5 AS weight, 'しつどが　ひくい　とちで　くらす　サンドパンほど　せなかの　トゲの　てざわりは　かたく　なめらかになる。' AS description, current_timestamp
UNION ALL SELECT 29 AS number, 'ニドラン♀' AS name, 'どくばりポケモン'   AS category, 'どく' AS type1, '' AS type2, 0.4 AS height, 7.0 AS weight, 'からだは　ちいさくても　どくばりを　もつため　ちゅういが　ひつようだ。めすのほうが　ツノが　ちいさい。' AS description, current_timestamp
UNION ALL SELECT 30 AS number, 'ニドリーナ' AS name, 'どくばりポケモン'   AS category, 'どく' AS type1, '' AS type2, 0.8 AS height, 20.0 AS weight, 'メスなので　せいかくは　おんこう。　くちから　だす　ちょうおんぱはあいてを　まどわす　ちからがある。' AS description, current_timestamp
UNION ALL SELECT 31 AS number, 'ニドクイン' AS name, 'ドリルポケモン'   AS category, 'どく' AS type1, 'じめん' AS type2, 1.3 AS height, 60.0 AS weight, 'ウロコで　おおわれた　がんじょうなからだで　すあなの　いりぐちをふさぎてきから　こどもたちを　まもる。' AS description, current_timestamp
UNION ALL SELECT 32 AS number, 'ニドラン♂' AS name, 'どくばりポケモン'   AS category, 'どく' AS type1, '' AS type2, 0.5 AS height, 9.0 AS weight, 'くさむらの　うえに　みみだけ　だしてまわりの　けはいを　さぐる。　もうどくの　ツノで　みを　まもる。' AS description, current_timestamp
UNION ALL SELECT 33 AS number, 'ニドリーノ' AS name, 'どくばりポケモン'   AS category, 'どく' AS type1, '' AS type2, 0.9 AS height, 19.5 AS weight, 'はったつした　みみを　たててまわりの　けはいを　さぐる。なにかあると　すぐに　とびかかる。' AS description, current_timestamp
UNION ALL SELECT 34 AS number, 'ニドキング' AS name, 'ドリルポケモン'   AS category, 'どく' AS type1, 'じめん' AS type2, 1.4 AS height, 62.0 AS weight, 'いしのように　かたい　ひふとながあく　のびた　ツノが　とくちょう。　ツノには　どくもあるので　ちゅうい。' AS description, current_timestamp
UNION ALL SELECT 35 AS number, 'ピッピ' AS name, 'ようせいポケモン'   AS category, 'フェアリー' AS type1, '' AS type2, 0.6 AS height, 7.5 AS weight, 'まんげつのよる　ピッピが　あつまって　ダンスを　おどるようすを　みると　しあわせに　なれると　いわれている。' AS description, current_timestamp
UNION ALL SELECT 36 AS number, 'ピクシー'  AS name, 'ようせいポケモン' AS category, 'フェアリー'   AS type1, '' AS type2, 1.3 AS height, 40.0 AS weight, 'ようせいの　なかまで　めったに　ひとまえに　でてこない。　けはいを　かんじて　すぐ　にげて　しまうようだ。'     AS description, current_timestamp
UNION ALL SELECT 37 AS number, 'ロコン' AS name, 'きつねポケモン'   AS category, 'ほのお' AS type1, '' AS type2, 0.6 AS height, 9.9 AS weight, 'こどもだが　６ぽんの　しっぽが　うつくしい。　せいちょうすると　さらに　しっぽが　ふえる。' AS description, current_timestamp
UNION ALL SELECT 38 AS number, 'キュウコン' AS name, 'きつねポケモン'   AS category, 'ほのお' AS type1, '' AS type2, 1.1 AS height, 19.9 AS weight, 'しっぽの　いっぽん　いっぽんに　じんつうりきが　こめられている。　1000ねん　いきると　いわれる。' AS description, current_timestamp
UNION ALL SELECT 39 AS number, 'プリン' AS name, 'ふうせんポケモン'   AS category, 'ノーマル' AS type1, 'フェアリー' AS type2, 0.5 AS height, 5.5 AS weight, 'はいかつりょうは　ポケモンかいでも　トップクラス。　あいてが　ねむるまで　こもりうたを　うたいつづけるぞ。' AS description, current_timestamp
UNION ALL SELECT 40 AS number, 'プクリン' AS name, 'ふうせんポケモン'   AS category, 'ノーマル' AS type1, 'フェアリー' AS type2, 1.0 AS height, 12.0 AS weight, 'いきを　すえば　すうほど　ふくらむ。　ふきげんになると　からだを　おおきく　ふくらませて　あいてを　いあつする。' AS description, current_timestamp;
SELECT * FROM pokedex_kanto order by number asc;
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/a68b5b5b-755f-c128-be8c-ccb6361b33dc.png)
おおー、登録できました！！
この書き方を使用すると、**どのカラムにどの値を入れるかというのがわかりやすい**ですね！

とにかく、**「まだ登録されていないデータを`SELECT`で記述して内容を`INSERT`することができる」**ということがわかりました。

SELECT文について少し深堀りと、今回使ったUINIONについて勉強してみます。

##【復習】SELECT文
[以前書いた記事](https://qiita.com/takahirocook/items/89aba8585dcd42dd310f)の抜粋ですが、改めて使い方を復習したいと思います。
まず、SELECT文の基本的な構文ははこちらです。

```
SELECT 取得したいカラム名 FROM テーブル名 WHERE 条件;
```
記述の手順としては..

1. **`SELECT`**を宣言し、検索したい**カラムを指定**する。
2. **`FROM`**を宣言し、検索したい**テーブルを指定**する。
3. **`WHERE`**を宣言し、検索したい**行の条件を指定**する。

この３ステップで記述します。
ここまではいままでもつかってきましたが、ここから以下は補足になります。

###架空のレコードをSELECTする
**FROM句なしでSELECTを実行すると**自分の好きなようにSELECT結果をカスタマイズできます。
つまり、**まだ登録されていない（存在しない）データをSELECT結果として出力することができます。**

####例
値とカラムを出力する場合はこのような書き方になります。**値とカラムは`AS`をつかって結びつけてあげましょう。**
そしてお約束になりますが、**他のカラムを追記する場合はカンマ区切り**してつなげてあげます。

```sql
SELECT '値1' AS カラム名1,'値2' AS カラム名2,'値3' AS カラム名3
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/e1fc137f-7919-9379-d6f1-4eb1f0645953.png)
↑こちらの出力結果はまだテーブルにINSERTされていない内容です。
つまり、**存在しない架空のデータということになります！**

ただ、このままだと一行のSELECT結果しか表示させることができないため、**`UNION句`**というものをつかってあげることで複数のSELECT結果を統合して表示することができます！

##UNION句

UNION句をつかうと２つ以上のをSELECT結果を統合して表示することができます。
###UNIONの書き方
基本的な書き方がこちらです。

```
SELECT '値1' AS カラム名
UNION ALL
SELECT '値2' AS カラム名;
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/7ca49795-9250-2e20-fa24-a5dffeb66037.png)
このように、複数の結果を統合して表示ができました（UNIONでつながないと１つの結果しか表示されない）。

###UNIONを使う条件
UNION句で統合する複数のSELECT文は、**2つの条件を満たしている必要があります。**

1. **SELECT句に指定するカラムのデータ型が同じか、もしくは、変換可能であること**
2. **SELECT句のカラム数が同じこと**

つまり、**「一緒に表示するSELECT結果は条件を揃えてね」**ということですね。
それさえ満たしていれば、先程のように大量のカラムと値を表示させることが可能です。
**複数のカラムを繋げる場合はカンマでくぎってつなげてあげましょう。**

```sql
SELECT '値1' AS カラム名1,'値2' AS カラム名2,'値3' AS カラム名3
UNION ALL
SELECT '値4' AS カラム名1,'値5' AS カラム名2,'値6' AS カラム名3;
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/5e6145e1-75e1-ab1a-a49b-9b2d86f3163f.png)

###UNION と UNION ALL
UNION には普通( ? ) の UNION と ALL UNIONがあります。

- **UNIONは重複した値は表示しない**
- **UNION ALLは重複した値も表示する**

といった違いがあります。

UNIONは重複しているか裏でチェックがされるため、チェックのないUNION ALLと比較すると遅くなります。
uniqueの値はUNIONがいいかもしれませんが、**特に理由がなければUNION ALLにしておきましょう。**

##登録したポケモンを確認する

PART5にもなったので、そろそろ登録されたポケモンも半分くらいになったかと思いますので、現在ポケモン図鑑に登録されている数を調べてみたいと思います。
テーブルにレコード（登録されているもの）が何件あるか表示させるための構文はこちらです。

```
select count(*) from テーブル名;
```

現在ポケモン図鑑に登録されている数を集計します。

```sql
select count(*) from pokedex_kanto;
```
実行結果
![あと４６匹](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/06a932be-9b7c-baf6-d311-75b5c4a1cdba.png)
３分の１（以下）でした。