Chapter14 表の結合とビュー

概要と目標 リレーショナルデータベースの真骨頂!
テーブルを結合しよう。

複数のテーブルからデータを取り出し、寄せ集めて表示することが出来ます。
欲しいレコードが抽出できるようにテーブルの結合方法を学習しましょう。

今回のゴール

コマンドプロンプト

mysql> select p.title, u.name
    ->   from posts as p join users as u
    ->   on p.user_id = u.id;
+-----------------------------------+--------+
| title                             | name   |
+-----------------------------------+--------+
| 2回目の投稿!                     | 前田   |
| ブログ始めました                  | 大島   |
| そろそろ・・・                    | 高橋   |
| まだやってます                    | 高橋   |
| 久しぶりの投稿                    | 高橋   |
| また、空いちゃいました            | 高橋   |
| 限界です                          | 高橋   |
| おいしいお店発見!                | 指原   |
| また、行っちゃいました            | 指原   |
| 一人旅してます                    | 山本   |
+-----------------------------------+--------+
10 rows in set (0.00 sec)

mysql> select u.name, count(*) as total
    ->   from posts as p join users as u
    ->   on p.user_id = u.id
    ->   group by p.user_id;
+--------+-------+
| name   | total |
+--------+-------+
| 前田   |     1 |
| 大島   |     1 |
| 高橋   |     5 |
| 指原   |     2 |
| 山本   |     1 |
+--------+-------+
5 rows in set (0.00 sec)

mysql> select p.id, p.title, p.content, u.name
    ->   from posts as p join users as u
    ->   on p.user_id = u.id
    ->   where p.user_id in(3,4)
    ->   order by p.created desc
    ->   limit 5;
+----+-----------------------------------+-----------------------------------------------------------------------------------------------------------+--------+
| id | title                             | content                                                                                                   | name   |
+----+-----------------------------------+-----------------------------------------------------------------------------------------------------------+--------+
| 10 | 限界です                          | こんにちは、もうブログを続けるのは限界です。                                                              | 高橋   |
|  9 | また、行っちゃいました            | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 指原   |
|  7 | おいしいお店発見!                | こんにちは、おいしいパスタのお店を発見しました。                                                          | 指原   |
|  6 | また、空いちゃいました            | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 高橋   |
|  5 | 久しぶりの投稿                    | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 高橋   |
+----+-----------------------------------+-----------------------------------------------------------------------------------------------------------+--------+
5 rows in set (0.01 sec)

mysql> create view view2
    ->   as
    ->     select p.*, u.name, u.email
    ->       from posts as p join users as u
    ->       on p.user_id = u.id;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from view2 order by created desc;
+----+---------+-----------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+--------+---------------------+
| id | user_id | title                             | content                                                                                                   | created     | modified            | name   | email               |
+----+---------+-----------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+--------+---------------------+
| 10 |       3 | 限界です                          | こんにちは、もうブログを続けるのは限界です。                                                              | 2017-07-18 10:00:00 | 2017-07-18 10:00:00 | 高橋   | takahashi@dummy.com |
|  9 |       4 | また、行っちゃいました            | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 2017-07-17 10:00:00 | 2017-07-17 10:00:00 | 指原   | sashihara@dummy.jp  |
|  7 |       4 | おいしいお店発見!                | こんにちは、おいしいパスタのお店を発見しました。                                                          | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 | 指原   | sashihara@dummy.jp  |
|  8 |       5 | 一人旅してます                    | こんにちは。今、北海道にいてます。一人旅してます。                                                        | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 | 山本   | yamamoto@dummy.net  |
|  6 |       3 | また、空いちゃいました            | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 2017-05-31 10:00:00 | 2017-05-31 10:00:00 | 高橋   | takahashi@dummy.com |
|  5 |       3 | 久しぶりの投稿                    | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 2017-05-01 10:00:00 | 2017-05-01 10:00:00 | 高橋   | takahashi@dummy.com |
|  4 |       3 | まだやってます                    | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       | 2017-04-11 10:00:00 | 2017-04-11 10:00:00 | 高橋   | takahashi@dummy.com |
|  3 |       3 | そろそろ・・・                    | こんにちは、そろそろネタが尽きてきました。                                                                | 2017-04-09 10:00:00 | 2017-04-09 10:00:00 | 高橋   | takahashi@dummy.com |
|  2 |       1 | 2回目の投稿!                     | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   | 2017-04-08 10:00:00 | 2017-04-08 10:00:00 | 前田   | maeda@dummy.com     |
|  1 |       2 | ブログ始めました                  | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      | 2017-04-07 10:00:00 | 2017-04-07 10:00:00 | 大島   | oshima@dummy.com    |
+----+---------+-----------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+--------+---------------------+
10 rows in set (0.01 sec)

mysql> drop view view2;
Query OK, 0 rows affected (0.00 sec)

mysql>  

テーブルの和結合 同じフィールド数の複数テーブルから
データを集める。

UNION」を使えば、同じフィールド数の複数のテーブルを合わせて表示できる。
同じフィールド数であれば、データの型などが違っていても結合できる。

基本的な和結合のSELECT構文
SELECT 表示するフィールド名 FROM テーブル名
  UNION [オプション]
  SELECT 表示するフィールド名 FROM 結合するテーブル名;

[〜]: 省略可能
オプション: DISTINCT ・・・ 重複は削除(デフォルト) / ALL ・・・ 重複も表示
表示するフィールド名: 「,(半角カンマ)」区切りで複数指定できる。
                    「*(アスタリスク)」 を指定すると全てフィールドが表示される。
                     結合するテーブルはフィールド数を同じにする必要がある。

詳細は13.2.9 SELECT 構文を参照

和結合で複数のテーブルのデータを
抽出してみよう。

  1. MySQLモニタを起動
  2. 前回のレッスンで使用したデータベースがない場合は、
    「chapter14」 › 「settings」 › 「該当文字コード」フォルダ内の「setting.sql」を
    sourceコマンド、またはファイルの内容をコピー&ペーストし、
    今回のレッスンに必要なデータベースとテーブル、レコードを作成する
source /php-lessons/chapter14/settings/Shift-JIS/settings.sql;

ファイルパスは変更(コマンドラインツールにドラッグ&ドロップ)して下さい

実行例

コマンドプロンプト

mysql> source /php-lessons/chapter14/settings/Shift-JIS/settings.sql
Query OK, 3 rows affected (0.01 sec)

Query OK, 1 row affected (0.00 sec)

Database changed
Query OK, 0 rows affected, 1 warning (0.00 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected, 1 warning (0.00 sec)

Query OK, 0 rows affected (0.02 sec)

Query OK, 10 rows affected (0.00 sec)
Records: 10  Duplicates: 0  Warnings: 0

Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

+----+---------+-----------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+
| id | user_id | title                             | content                                                                                                   | created     | modified            |
+----+---------+-----------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+
|  1 |       2 | ブログ始めました                  | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      | 2017-04-07 10:00:00 | 2017-04-07 10:00:00 |
|  2 |       1 | 2回目の投稿!                     | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   | 2017-04-08 10:00:00 | 2017-04-08 10:00:00 |
|  3 |       3 | そろそろ・・・                    | こんにちは、そろそろネタが尽きてきました。                                                                | 2017-04-09 10:00:00 | 2017-04-09 10:00:00 |
|  4 |       3 | まだやってます                    | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       | 2017-04-11 10:00:00 | 2017-04-11 10:00:00 |
|  5 |       3 | 久しぶりの投稿                    | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 2017-05-01 10:00:00 | 2017-05-01 10:00:00 |
|  6 |       3 | また、空いちゃいました            | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 2017-05-31 10:00:00 | 2017-05-31 10:00:00 |
|  7 |       4 | おいしいお店発見!                | こんにちは、おいしいパスタのお店を発見しました。                                                          | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 |
|  8 |       5 | 一人旅してます                    | こんにちは。今、北海道にいてます。一人旅してます。                                                        | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 |
|  9 |       4 | また、行っちゃいました            | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 2017-07-17 10:00:00 | 2017-07-17 10:00:00 |
| 10 |       3 | 限界です                          | こんにちは、もうブログを続けるのは限界です。                                                              | 2017-07-18 10:00:00 | 2017-07-18 10:00:00 |
+----+---------+-----------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+
10 rows in set (0.00 sec)

+----+--------+---------------------+------------+---------------------+---------------------+
| id | name   | email               | password   | created             | modified            |
+----+--------+---------------------+------------+---------------------+---------------------+
|  1 | 前田   | maeda@dummy.com     | maemae     | 2017-04-03 10:00:00 | 2017-07-15 10:00:00 |
|  2 | 大島   | oshima@dummy.com    | oshioshi   | 2017-04-05 10:00:00 | 2017-04-05 10:00:00 |
|  3 | 高橋   | takahashi@dummy.com | takataka   | 2017-04-07 10:00:00 | 2017-05-10 10:00:00 |
|  4 | 指原   | sashihara@dummy.jp  | sashisashi | 2017-07-14 10:00:00 | 2017-07-20 10:00:00 |
|  5 | 山本   | yamamoto@dummy.net  | yamayama   | 2017-07-14 10:00:00 | 2017-08-10 10:00:00 |
+----+--------+---------------------+------------+---------------------+---------------------+
5 rows in set (0.00 sec)

mysql>  
  1. 下記のコマンドをコマンドラインツールにコピー&ペーストして、
    posts」テーブルからコピーした新たな「new_posts」テーブルを作成すると共に、
    レコードも3件追加する
-- テーブルのフィールド構造とデータのコピー
create table new_posts select * from posts;

-- レコードを追加
insert into new_posts
  values (
    11,
    1,
    '新規ブログを立ち上げました!',
    'こんにちは。今回新しくブログを立ち上げました。',
    '2018/04/08 10:00:00',
    '2018/04/08 10:00:00'
  ),
  (
    12,
    6,
    '新メンバーの紹介',
    'みなさんどうもはじめまして。新メンバーです。',
    '2018/04/9 10:00:00',
    '2018/04/9 10:00:00'
  ),
  (
    13,
    2,
    '本当に最後の投稿',
    'こんにちは、これがホントに最後の投稿になります。',
    '2018/04/10 10:00:00',
    '2018/04/10 10:00:00'
  );

-- レコードの表示
select * from new_posts;
実行例

コマンドプロンプト

mysql> create table new_posts select * from posts;
Query OK, 10 rows affected (0.03 sec)
Records: 10  Duplicates: 0  Warnings: 0

mysql>
mysql> -- レコードを追加
mysql> insert into new_posts
    ->   values (
    ->     11,
    ->     1,
    ->     '新規ブログを立ち上げました!',
    ->     'こんにちは。今回新しくブログを立ち上げました。',
    ->     '2018/04/08 10:00:00',
    ->     '2018/04/08 10:00:00'
    ->   ),
    ->   (
    ->     12,
    ->     6,
    ->     '新メンバーの紹介',
    ->     'みなさんどうもはじめまして。新メンバーです。',
    ->     '2018/04/9 10:00:00',
    ->     '2018/04/9 10:00:00'
    ->   ),
    ->   (
    ->     13,
    ->     2,
    ->     '本当に最後の投稿',
    ->     'こんにちは、これがホントに最後の投稿になります。',
    ->     '2018/04/10 10:00:00',
    ->     '2018/04/10 10:00:00'
    ->   );
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql>
mysql> -- レコードの表示
mysql> select * from new_posts;
+----+---------+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+
| id | user_id | title                                      | content                                                                                                   | created             | modified            |
+----+---------+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+
|  1 |       2 | ブログ始めました                           | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      | 2017-04-07 10:00:00 | 2017-04-07 10:00:00 |
|  2 |       1 | 2回目の投稿!                              | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   | 2017-04-08 10:00:00 | 2017-04-08 10:00:00 |
|  3 |       3 | そろそろ・・・                             | こんにちは、そろそろネタが尽きてきました。                                                                | 2017-04-09 10:00:00 | 2017-04-09 10:00:00 |
|  4 |       3 | まだやってます                             | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       | 2017-04-11 10:00:00 | 2017-04-11 10:00:00 |
|  5 |       3 | 久しぶりの投稿                             | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 2017-05-01 10:00:00 | 2017-05-01 10:00:00 |
|  6 |       3 | また、空いちゃいました                     | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 2017-05-31 10:00:00 | 2017-05-31 10:00:00 |
|  7 |       4 | おいしいお店発見!                         | こんにちは、おいしいパスタのお店を発見しました。                                                          | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 |
|  8 |       5 | 一人旅してます                             | こんにちは。今、北海道にいてます。一人旅してます。                                                        | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 |
|  9 |       4 | また、行っちゃいました                     | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 2017-07-17 10:00:00 | 2017-07-17 10:00:00 |
| 10 |       3 | 限界です                                   | こんにちは、もうブログを続けるのは限界です。                                                              | 2017-07-18 10:00:00 | 2017-07-18 10:00:00 |
| 11 |       1 | 新規ブログを立ち上げました!               | こんにちは。今回新しくブログを立ち上げました。                                                            | 2018-04-08 10:00:00 | 2018-04-08 10:00:00 |
| 12 |       6 | 新メンバーの紹介                           | みなさんどうもはじめまして。新メンバーです。                                                              | 2018-04-09 10:00:00 | 2018-04-09 10:00:00 |
| 13 |       2 | 本当に最後の投稿                           | こんにちは、これがホントに最後の投稿になります。                                                          | 2018-04-10 10:00:00 | 2018-04-10 10:00:00 |
+----+---------+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+
13 rows in set (0.00 sec)

mysql>  
  1. 「chapter14」フォルダ内の「select.sql」をテキストエディタで開く
  2. posts」テーブルと「users」テーブルを結合するコマンドを記述し、
    コマンドラインツールにコピー&ペースト
chapter14/select.sql
-- テーブルの和結合
-- 「posts」テーブルに「new_posts」テーブルを和結合
select * from posts union select * from new_posts;
実行例

コマンドプロンプト

mysql> select * from posts union select * from new_posts;
+----+---------+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+
| id | user_id | title                                      | content                                                                                                   | created             | modified            |
+----+---------+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+
|  1 |       2 | ブログ始めました                           | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      | 2017-04-07 10:00:00 | 2017-04-07 10:00:00 |
|  2 |       1 | 2回目の投稿!                              | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   | 2017-04-08 10:00:00 | 2017-04-08 10:00:00 |
|  3 |       3 | そろそろ・・・                             | こんにちは、そろそろネタが尽きてきました。                                                                | 2017-04-09 10:00:00 | 2017-04-09 10:00:00 |
|  4 |       3 | まだやってます                             | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       | 2017-04-11 10:00:00 | 2017-04-11 10:00:00 |
|  5 |       3 | 久しぶりの投稿                             | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 2017-05-01 10:00:00 | 2017-05-01 10:00:00 |
|  6 |       3 | また、空いちゃいました                     | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 2017-05-31 10:00:00 | 2017-05-31 10:00:00 |
|  7 |       4 | おいしいお店発見!                         | こんにちは、おいしいパスタのお店を発見しました。                                                          | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 |
|  8 |       5 | 一人旅してます                             | こんにちは。今、北海道にいてます。一人旅してます。                                                        | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 |
|  9 |       4 | また、行っちゃいました                     | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 2017-07-17 10:00:00 | 2017-07-17 10:00:00 |
| 10 |       3 | 限界です                                   | こんにちは、もうブログを続けるのは限界です。                                                              | 2017-07-18 10:00:00 | 2017-07-18 10:00:00 |
| 11 |       1 | 新規ブログを立ち上げました!               | こんにちは。今回新しくブログを立ち上げました。                                                            | 2018-04-08 10:00:00 | 2018-04-08 10:00:00 |
| 12 |       6 | 新メンバーの紹介                           | みなさんどうもはじめまして。新メンバーです。                                                              | 2018-04-09 10:00:00 | 2018-04-09 10:00:00 |
| 13 |       2 | 本当に最後の投稿                           | こんにちは、これがホントに最後の投稿になります。                                                          | 2018-04-10 10:00:00 | 2018-04-10 10:00:00 |
+----+---------+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+
13 rows in set (0.01 sec)

mysql> 

デフォルトでは重複したレコードは表示されない


和結合で重複したデータも
抽出してみよう。

  1. 「chapter14」フォルダ内の「select.sql」をテキストエディタで開く
  2. UNION」に「ALL」オプションを付加したコマンドを記述し、
    コマンドラインツールにコピー&ペースト
chapter14/select.sql
-- 「posts」テーブルに「new_posts」テーブルを和結合(重複も表示)
select * from posts union all select * from new_posts;
実行例

コマンドプロンプト

mysql> select * from posts union all select * from new_posts;
+----+---------+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+
| id | user_id | title                                      | content                                                                                                   | created             | modified            |
+----+---------+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+
|  1 |       2 | ブログ始めました                           | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      | 2017-04-07 10:00:00 | 2017-04-07 10:00:00 |
|  2 |       1 | 2回目の投稿!                              | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   | 2017-04-08 10:00:00 | 2017-04-08 10:00:00 |
|  3 |       3 | そろそろ・・・                             | こんにちは、そろそろネタが尽きてきました。                                                                | 2017-04-09 10:00:00 | 2017-04-09 10:00:00 |
|  4 |       3 | まだやってます                             | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       | 2017-04-11 10:00:00 | 2017-04-11 10:00:00 |
|  5 |       3 | 久しぶりの投稿                             | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 2017-05-01 10:00:00 | 2017-05-01 10:00:00 |
|  6 |       3 | また、空いちゃいました                     | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 2017-05-31 10:00:00 | 2017-05-31 10:00:00 |
|  7 |       4 | おいしいお店発見!                         | こんにちは、おいしいパスタのお店を発見しました。                                                          | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 |
|  8 |       5 | 一人旅してます                             | こんにちは。今、北海道にいてます。一人旅してます。                                                        | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 |
|  9 |       4 | また、行っちゃいました                     | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 2017-07-17 10:00:00 | 2017-07-17 10:00:00 |
| 10 |       3 | 限界です                                   | こんにちは、もうブログを続けるのは限界です。                                                              | 2017-07-18 10:00:00 | 2017-07-18 10:00:00 |
|  1 |       2 | ブログ始めました                           | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      | 2017-04-07 10:00:00 | 2017-04-07 10:00:00 |
|  2 |       1 | 2回目の投稿!                              | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   | 2017-04-08 10:00:00 | 2017-04-08 10:00:00 |
|  3 |       3 | そろそろ・・・                             | こんにちは、そろそろネタが尽きてきました。                                                                | 2017-04-09 10:00:00 | 2017-04-09 10:00:00 |
|  4 |       3 | まだやってます                             | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       | 2017-04-11 10:00:00 | 2017-04-11 10:00:00 |
|  5 |       3 | 久しぶりの投稿                             | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 2017-05-01 10:00:00 | 2017-05-01 10:00:00 |
|  6 |       3 | また、空いちゃいました                     | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 2017-05-31 10:00:00 | 2017-05-31 10:00:00 |
|  7 |       4 | おいしいお店発見!                         | こんにちは、おいしいパスタのお店を発見しました。                                                          | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 |
|  8 |       5 | 一人旅してます                             | こんにちは。今、北海道にいてます。一人旅してます。                                                        | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 |
|  9 |       4 | また、行っちゃいました                     | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 2017-07-17 10:00:00 | 2017-07-17 10:00:00 |
| 10 |       3 | 限界です                                   | こんにちは、もうブログを続けるのは限界です。                                                              | 2017-07-18 10:00:00 | 2017-07-18 10:00:00 |
| 11 |       1 | 新規ブログを立ち上げました!               | こんにちは。今回新しくブログを立ち上げました。                                                            | 2018-04-08 10:00:00 | 2018-04-08 10:00:00 |
| 12 |       6 | 新メンバーの紹介                           | みなさんどうもはじめまして。新メンバーです。                                                              | 2018-04-09 10:00:00 | 2018-04-09 10:00:00 |
| 13 |       2 | 本当に最後の投稿                           | こんにちは、これがホントに最後の投稿になります。                                                          | 2018-04-10 10:00:00 | 2018-04-10 10:00:00 |
+----+---------+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+
23 rows in set (0.01 sec)

mysql> 

テーブルの内部結合 複数のテーブルを結合し、
レコードを抽出。

複数のテーブルを「キー」によって結びつけて、
一致するレコードのみ抽出する結合を「内部結合」という。
内部結合は「INNER JOIN」句で結合するテーブルを指定し、
ON」句で結びつけるキーを指定する。

INNER JOINを用いたSELECT構文
SELECT 表示するテーブル名.表示するフィールド名
  FROM テーブル名 [INNER] JOIN 結合するテーブル名
  ON テーブル名.関連付けるフィールド名 = 結合するテーブル名.関連付けるフィールド名;

[〜]: 省略可能
表示するフィールド名: 「,(半角カンマ)」区切りで複数指定できる。
                    「*(アスタリスク)」 を指定すると全てフィールドが表示される。

詳細は13.2.9 SELECT 構文を参照

内部結合で複数のテーブルを
結合してみよう。

  1. 「chapter14」フォルダ内の「select.sql」をテキストエディタで開く
  2. 「posts」テーブルの「id」、「title」、「content」、「user_id」フィールドと
    「users」テーブルの「name」フィールドを内部結合するコマンドを記述し、
    コマンドラインツールにコピー&ペースト
chapter14/select.sql
-- テーブルの内部結合
-- 「posts」テーブルの「id」、「title」、「content」、「user_id」と
-- 「users」テーブルの「name」フィールドのキーが一致するレコードを抽出
select posts.id, posts.title, posts.content, posts.user_id, users.name
  from posts join users
  on posts.user_id = users.id;
実行例

コマンドプロンプト

mysql> select posts.id, posts.title, posts.content, posts.user_id, users.name
    ->   from posts join users
    ->   on posts.user_id = users.id;
+----+-----------------------------------+-----------------------------------------------------------------------------------------------------------+---------+--------+
| id | title                             | content                                                                                                   | user_id | name   |
+----+-----------------------------------+-----------------------------------------------------------------------------------------------------------+---------+--------+
|  2 | 2回目の投稿!                     | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   |       1 | 前田   |
|  1 | ブログ始めました                  | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      |       2 | 大島   |
|  3 | そろそろ・・・                    | こんにちは、そろそろネタが尽きてきました。                                                                |       3 | 高橋   |
|  4 | まだやってます                    | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       |       3 | 高橋   |
|  5 | 久しぶりの投稿                    | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        |       3 | 高橋   |
|  6 | また、空いちゃいました            | お久しぶりです。またまた日が空いてしまいましたね。                                                        |       3 | 高橋   |
| 10 | 限界です                          | こんにちは、もうブログを続けるのは限界です。                                                              |       3 | 高橋   |
|  7 | おいしいお店発見!                | こんにちは、おいしいパスタのお店を発見しました。                                                          |       4 | 指原   |
|  9 | また、行っちゃいました            | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    |       4 | 指原   |
|  8 | 一人旅してます                    | こんにちは。今、北海道にいてます。一人旅してます。                                                        |       5 | 山本   |
+----+-----------------------------------+-----------------------------------------------------------------------------------------------------------+---------+--------+
10 rows in set (0.00 sec)

mysql>  

並び順を指定しない場合は、関連付けたキーの昇順で並ぶ


内部結合したレコードの
並び順を変更してみよう。

  1. 「chapter14」フォルダ内の「select.sql」をテキストエディタで開く
  2. 「posts」テーブルの「id」、「title」、「content」フィールドと
    「users」テーブルの「name」フィールドを、「posts」テーブルの「id」の降順で、
    レコードを抽出する内部結合のコマンドを記述し、コマンドラインツールにコピー&ペースト
chapter14/select.sql
-- 「posts」テーブルの「id」、「title」、「content」と
-- 「users」テーブルの「name」フィールドのキーが一致するレコードを
-- 「posts」テーブルの「id」の降順で抽出
select posts.id, posts.title, posts.content, users.name
  from posts join users
  on posts.user_id = users.id
  order by posts.id desc;
実行例

コマンドプロンプト

mysql> select posts.id, posts.title, posts.content, users.name
    ->   from posts join users
    ->   on posts.user_id = users.id
    ->   order by posts.id desc;
+----+-----------------------------------+-----------------------------------------------------------------------------------------------------------+--------+
| id | title                             | content                                                                                                   | name   |
+----+-----------------------------------+-----------------------------------------------------------------------------------------------------------+--------+
| 10 | 限界です                          | こんにちは、もうブログを続けるのは限界です。                                                              | 高橋   |
|  9 | また、行っちゃいました            | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 指原   |
|  8 | 一人旅してます                    | こんにちは。今、北海道にいてます。一人旅してます。                                                        | 山本   |
|  7 | おいしいお店発見!                | こんにちは、おいしいパスタのお店を発見しました。                                                          | 指原   |
|  6 | また、空いちゃいました            | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 高橋   |
|  5 | 久しぶりの投稿                    | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 高橋   |
|  4 | まだやってます                    | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       | 高橋   |
|  3 | そろそろ・・・                    | こんにちは、そろそろネタが尽きてきました。                                                                | 高橋   |
|  2 | 2回目の投稿!                     | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   | 前田   |
|  1 | ブログ始めました                  | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      | 大島   |
+----+-----------------------------------+-----------------------------------------------------------------------------------------------------------+--------+
10 rows in set (0.01 sec)

mysql>  

プチ問題

new_posts」テーブルの「id」、「title」、「content」、「created」と
「users」テーブルの「name」フィールドのキーが一致するレコードを
「new_posts」テーブルの「created」が 新しい順に抽出

chapter14/select.sql
-- 「new_posts」テーブルの「id」、「title」、「content」、「created」と
-- 「users」テーブルの「name」フィールドのキーが一致するレコードを
-- 「new_posts」テーブルの「created」が新しい順に抽出
select new_posts.id, new_posts.title, new_posts.content, new_posts.created, users.name
  from new_posts join users
  on new_posts.user_id = users.id
  order by new_posts.created desc;

答えを見る

実行例

コマンドプロンプト

mysql> [「new_posts」テーブルの「id」、「title」、「content」、「created」と
                   「users」テーブルの「name」フィールドのキーが一致するレコードを
                   「new_posts」テーブルの「created」が 新しい順に抽出]
+----+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+--------+
| id | title                                      | content                                                                                                   | created    | name   |
+----+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+--------+
| 13 | 本当に最後の投稿                           | こんにちは、これがホントに最後の投稿になります。                                                          | 2018-04-10 10:00:00 | 大島   |
| 11 | 新規ブログを立ち上げました!               | こんにちは。今回新しくブログを立ち上げました。                                                            | 2018-04-08 10:00:00 | 前田   |
| 10 | 限界です                                   | こんにちは、もうブログを続けるのは限界です。                                                              | 2017-07-18 10:00:00 | 高橋   |
|  9 | また、行っちゃいました                     | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 2017-07-17 10:00:00 | 指原   |
|  7 | おいしいお店発見!                         | こんにちは、おいしいパスタのお店を発見しました。                                                          | 2017-07-15 10:00:00 | 指原   |
|  8 | 一人旅してます                             | こんにちは。今、北海道にいてます。一人旅してます。                                                        | 2017-07-15 10:00:00 | 山本   |
|  6 | また、空いちゃいました                     | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 2017-05-31 10:00:00 | 高橋   |
|  5 | 久しぶりの投稿                             | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 2017-05-01 10:00:00 | 高橋   |
|  4 | まだやってます                             | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       | 2017-04-11 10:00:00 | 高橋   |
|  3 | そろそろ・・・                             | こんにちは、そろそろネタが尽きてきました。                                                                | 2017-04-09 10:00:00 | 高橋   |
|  2 | 2回目の投稿!                              | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   | 2017-04-08 10:00:00 | 前田   |
|  1 | ブログ始めました                           | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      | 2017-04-07 10:00:00 | 大島   |
+----+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+--------+
12 rows in set (0.01 sec)

mysql> 

関連付けるキーが存在しないレコードは表示されない。
存在しないレコードも表示する場合は外部結合を使う。

WHERE区での結合
上記の内部結合は、下記の様にFROM区で、結合するテーブルを半角カンマ区切りで記述し、
WHERE区でキーを関連させる記述方法もあります。
WHERE区で内部結合を行う例
-- 「posts」テーブルの「id」、「title」、「content」、「user_id」と「users」テーブルの「name」フィールドを全レコード抽出
select posts.id, posts.title, posts.content, posts.user_id, users.name
  from posts, users
  where posts.user_id = users.id;

テーブルの外部結合 キーが一致しないレコードも抽出。
そう。外部結合ならね。

複数のテーブルを「キー」によって結びつけて、
キーが一致しなくても、一方のテーブルのレコードは全て抽出する結合を「外部結合」という。
外部結合は「LEFT OUTER JOIN」句または、「RIGHT OUTER JOIN」句で
全て表示するテーブルと結合するテーブルを指定し、 「ON」句で結びつけるキーを指定する。

LEFT OUTER JOINを用いたSELECT構文
SELECT 表示するテーブル名.表示するフィールド名
  FROM 全レコード表示するテーブル名 LEFT [OUTER] JOIN 結合するテーブル名
  ON 全レコード表示するるテーブル名.関連付けるフィールド名 = 結合するテーブル名.関連付けるフィールド名;

[〜]: 省略可能
表示するフィールド名: 「,(半角カンマ)」区切りで複数指定できる。
                    「*(アスタリスク)」 を指定すると全てフィールドが表示される。

詳細は13.2.9 SELECT 構文を参照

RIGHT OUTER JOINを用いたSELECT構文
SELECT 表示するテーブル名.表示するフィールド名
  FROM 結合するテーブル名 RIGHT [OUTER] JOIN 全レコード表示するテーブル名
  ON 結合するテーブル名.関連付けるフィールド名 = 全レコード表示するテーブル名.関連付けるフィールド名;

[〜]: 省略可能
表示するフィールド名: 「,(半角カンマ)」区切りで複数指定できる。
                    「*(アスタリスク)」 を指定すると全てフィールドが表示される。

詳細は13.2.9 SELECT 構文を参照

外部結合で複数のテーブルを
結合してみよう。

  1. 「chapter14」フォルダ内の「select.sql」をテキストエディタで開く
  2. new_posts」テーブルの「id」、「title」、「content」、「created」と
    「users」テーブルの「name」フィールドを「new_posts」テーブルの「created」が
    新しい順に全レコードを抽出するコマンドを記述し、コマンドラインツールにコピー&ペースト
chapter14/select.sql
-- 外部結合
-- 「new_posts」テーブルの「id」、「title」、「content」、「created」と
-- 「users」テーブルの「name」フィールドを「new_posts」テーブルは全レコード
-- 「new_posts」テーブルの「created」が新しい順に抽出
select new_posts.id, new_posts.title, new_posts.content, new_posts.created, users.name
  from new_posts left join users
  on new_posts.user_id = users.id
  order by new_posts.created desc;
実行例

コマンドプロンプト

mysql> select new_posts.id, new_posts.title, new_posts.content, new_posts.created, users.name
    ->   from new_posts left join users
    ->   on new_posts.user_id = users.id
    ->   order by new_posts.created desc;
+----+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+--------+
| id | title                                      | content                                                                                                   | created    | name   |
+----+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+--------+
| 13 | 本当に最後の投稿                           | こんにちは、これがホントに最後の投稿になります。                                                          | 2018-04-10 10:00:00 | 大島   |
| 12 | 新メンバーの紹介                           | みなさんどうもはじめまして。新メンバーです。                                                              | 2018-04-09 10:00:00 | NULL   |
| 11 | 新規ブログを立ち上げました!               | こんにちは。今回新しくブログを立ち上げました。                                                            | 2018-04-08 10:00:00 | 前田   |
| 10 | 限界です                                   | こんにちは、もうブログを続けるのは限界です。                                                              | 2017-07-18 10:00:00 | 高橋   |
|  9 | また、行っちゃいました                     | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 2017-07-17 10:00:00 | 指原   |
|  7 | おいしいお店発見!                         | こんにちは、おいしいパスタのお店を発見しました。                                                          | 2017-07-15 10:00:00 | 指原   |
|  8 | 一人旅してます                             | こんにちは。今、北海道にいてます。一人旅してます。                                                        | 2017-07-15 10:00:00 | 山本   |
|  6 | また、空いちゃいました                     | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 2017-05-31 10:00:00 | 高橋   |
|  5 | 久しぶりの投稿                             | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 2017-05-01 10:00:00 | 高橋   |
|  4 | まだやってます                             | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       | 2017-04-11 10:00:00 | 高橋   |
|  3 | そろそろ・・・                             | こんにちは、そろそろネタが尽きてきました。                                                                | 2017-04-09 10:00:00 | 高橋   |
|  2 | 2回目の投稿!                              | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   | 2017-04-08 10:00:00 | 前田   |
|  1 | ブログ始めました                           | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      | 2017-04-07 10:00:00 | 大島   |
+----+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+--------+
13 rows in set (0.01 sec)

mysql>  

外部結合なら、キーが一致しないレコードも 「NULL」 として表示される

テーブルの相関名 何度も使うテーブル名には、
別名を付けると便利。

テーブル名もASキーワードで、別名を付けることができる。

相関名を用いた内部結合のSELECT構文
SELECT 表示する相関名.表示するフィールド名
  FROM テーブル名 AS 相関名 [INNER] JOIN 結合するテーブル名 AS 相関名
  ON 相関名.関連付けるフィールド名 = 結合する相関名.関連付けるフィールド名;

[〜]: 省略可能
表示するフィールド名: 「,(半角カンマ)」区切りで複数指定できる。
                    「*(アスタリスク)」 を指定すると全てフィールドが表示される。

詳細は13.2.9 SELECT 構文を参照

テーブルに相関名を付けて
記述を短くしてみよう。

  1. 「chapter14」フォルダ内の「select.sql」をテキストエディタで開く
  2. 「new_posts」テーブルに相関名「p」、「users」テーブルに相関名「u」、を付けて、
    テーブルを結合するコマンドを記述し、コマンドラインツールにコピー&ペースト
chapter14/select.sql
-- 相関名を付ける
-- 「new_posts」テーブルの「id」、「title」、「content」、「created」と
-- 「users」テーブルの「name」フィールドを「new_posts」テーブルは全レコード
-- 「new_posts」テーブルの「created」が新しい順に抽出
select p.id, p.title, p.content, p.created, u.name
  from new_posts as p left join users as u
  on p.user_id = u.id
  order by p.created desc;
実行例

コマンドプロンプト

mysql> select p.id, p.title, p.content, p.created, u.name
    ->   from new_posts as p left join users as u
    ->   on p.user_id = u.id
    ->   order by p.created desc;
+----+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+--------+
| id | title                                      | content                                                                                                   | created    | name   |
+----+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+--------+
| 13 | 本当に最後の投稿                           | こんにちは、これがホントに最後の投稿になります。                                                          | 2018-04-10 10:00:00 | 大島   |
| 12 | 新メンバーの紹介                           | みなさんどうもはじめまして。新メンバーです。                                                              | 2018-04-09 10:00:00 | NULL   |
| 11 | 新規ブログを立ち上げました!               | こんにちは。今回新しくブログを立ち上げました。                                                            | 2018-04-08 10:00:00 | 前田   |
| 10 | 限界です                                   | こんにちは、もうブログを続けるのは限界です。                                                              | 2017-07-18 10:00:00 | 高橋   |
|  9 | また、行っちゃいました                     | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 2017-07-17 10:00:00 | 指原   |
|  7 | おいしいお店発見!                         | こんにちは、おいしいパスタのお店を発見しました。                                                          | 2017-07-15 10:00:00 | 指原   |
|  8 | 一人旅してます                             | こんにちは。今、北海道にいてます。一人旅してます。                                                        | 2017-07-15 10:00:00 | 山本   |
|  6 | また、空いちゃいました                     | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 2017-05-31 10:00:00 | 高橋   |
|  5 | 久しぶりの投稿                             | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 2017-05-01 10:00:00 | 高橋   |
|  4 | まだやってます                             | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       | 2017-04-11 10:00:00 | 高橋   |
|  3 | そろそろ・・・                             | こんにちは、そろそろネタが尽きてきました。                                                                | 2017-04-09 10:00:00 | 高橋   |
|  2 | 2回目の投稿!                              | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   | 2017-04-08 10:00:00 | 前田   |
|  1 | ブログ始めました                           | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      | 2017-04-07 10:00:00 | 大島   |
+----+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+--------+
13 rows in set (0.01 sec)

mysql> 

抽出条件をビューに保存 抽出条件をテーブルのように保存。
それが、「ビュー」。

ビューは、SELECT文で抽出条件を、テーブルのように保存することができる。
保存したビューは、SELECT文で簡単にレコードを抽出できる。

CREATE VIEW構文
CREATE VIEW ビュー名 [(フィールド名1, フィールド名2, フィールド名3...)]
  AS 抽出条件のSELECT文;

[〜]: 省略可能
フィールド名: 「,(半角カンマ)」区切りで複数指定できる。
            列名を変更しない場合は省略可

詳細は13.1.20 CREATE VIEW 構文を参照

ビューを作成して、
抽出条件を保存してみよう。

  1. 「chapter14」フォルダ内の「view.sql」をテキストエディタで開く
  2. ビューを作成するコマンドを記述し、コマンドラインツールにコピー&ペースト
chapter14/view.sql
-- ビューを作成し、抽出条件を保存
create view view1 as
  select p.id, p.title, p.content, u.name, p.created
    from new_posts as p left join users as u
    on p.user_id = u.id
    order by p.created desc;

-- テーブル一の覧の表示 
show tables;
実行例

コマンドプロンプト

mysql> create view view1 as
    ->   select p.id, p.title, p.content, u.name, p.created
    ->     from new_posts as p left join users as u
    ->     on p.user_id = u.id
    ->     order by p.created desc;
Query OK, 0 rows affected (0.01 sec)

mysql>
mysql> -- テーブル一の覧の表示
mysql> show tables;
+-------------------+
| Tables_in_my_blog |
+-------------------+
| new_posts         |
| posts             |
| users             |
| view1             |
+-------------------+
4 rows in set (0.00 sec)

mysql> 

作成したビューを表示してみよう。

作成したビューは、テーブルと同じように扱える
従って、SELECTでレコードを抽出できる。

SELECT構文
SELECT 表示するフィールド名 FROM ビュー名;

表示するフィールド名: 「,(半角カンマ)」区切りで複数指定できる。
                    「*(アスタリスク)」 を指定すると全てフィールドが表示される。

詳細は13.2.9 SELECT 構文を参照

  1. 「chapter14」フォルダ内の「view.sql」をテキストエディタで開く
  2. view1の全レコードを表示するコマンドを記述し、コマンドラインツールにコピー&ペースト
chapter14/view.sql
-- ビューの表示
select * from view1;
実行例

コマンドプロンプト

mysql> select * from view1;
+----+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+--------+---------------------+
| id | title                                      | content                                                                                                   | name   | created             |
+----+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+--------+---------------------+
| 13 | 本当に最後の投稿                           | こんにちは、これがホントに最後の投稿になります。                                                          | 大島   | 2018-04-10 10:00:00 |
| 12 | 新メンバーの紹介                           | みなさんどうもはじめまして。新メンバーです。                                                              | NULL   | 2018-04-09 10:00:00 |
| 11 | 新規ブログを立ち上げました!               | こんにちは。今回新しくブログを立ち上げました。                                                            | 前田   | 2018-04-08 10:00:00 |
| 10 | 限界です                                   | こんにちは、もうブログを続けるのは限界です。                                                              | 高橋   | 2017-07-18 10:00:00 |
|  9 | また、行っちゃいました                     | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 指原   | 2017-07-17 10:00:00 |
|  7 | おいしいお店発見!                         | こんにちは、おいしいパスタのお店を発見しました。                                                          | 指原   | 2017-07-15 10:00:00 |
|  8 | 一人旅してます                             | こんにちは。今、北海道にいてます。一人旅してます。                                                        | 山本   | 2017-07-15 10:00:00 |
|  6 | また、空いちゃいました                     | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 高橋   | 2017-05-31 10:00:00 |
|  5 | 久しぶりの投稿                             | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 高橋   | 2017-05-01 10:00:00 |
|  4 | まだやってます                             | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       | 高橋   | 2017-04-11 10:00:00 |
|  3 | そろそろ・・・                             | こんにちは、そろそろネタが尽きてきました。                                                                | 高橋   | 2017-04-09 10:00:00 |
|  2 | 2回目の投稿!                              | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   | 前田   | 2017-04-08 10:00:00 |
|  1 | ブログ始めました                           | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      | 大島   | 2017-04-07 10:00:00 |
+----+--------------------------------------------+-----------------------------------------------------------------------------------------------------------+--------+---------------------+
13 rows in set (0.01 sec)

mysql> 

作成したビューを削除してみよう。

ビューの削除
DROP VIEW [IF EXISTS] ビュー名;

詳細は13.1.31 DROP VIEW 構文を参照

  1. 「chapter14」フォルダ内の「view.sql」をテキストエディタで開く
  2. view1を削除するコマンドを記述し、コマンドラインツールにコピー&ペースト
chapter14/view.sql
-- ビューの削除
drop view view1;
show tables;
実行例

コマンドプロンプト

mysql> drop view view1;
Query OK, 0 rows affected (0.00 sec)

mysql> show tables;
+-------------------+
| Tables_in_my_blog |
+-------------------+
| new_posts         |
| posts             |
| users             |
+-------------------+
3 rows in set (0.00 sec)

mysql> 

練習問題 今回の理解度をチェック。

「chapter14」フォルダ内の「training.sql」を利用し、以下の問題を解いて下さい。

実行例 (コマンド部分は省略)

コマンドプロンプト

mysql> [「posts」テーブルと「users」テーブルを
                   「user_id」をキーとして内部結合し
                   「title」フィールドと「name」フィールドのレコードを抽出]
+-----------------------------------+--------+
| title                             | name   |
+-----------------------------------+--------+
| 2回目の投稿!                     | 前田   |
| ブログ始めました                  | 大島   |
| そろそろ・・・                    | 高橋   |
| まだやってます                    | 高橋   |
| 久しぶりの投稿                    | 高橋   |
| また、空いちゃいました            | 高橋   |
| 限界です                          | 高橋   |
| おいしいお店発見!                | 指原   |
| また、行っちゃいました            | 指原   |
| 一人旅してます                    | 山本   |
+-----------------------------------+--------+
10 rows in set (0.00 sec)

mysql>
mysql> [「posts」テーブルと「users」テーブルを
        「user_id」をキーとして内部結合し
        「name」フィールドと「user_id」ごとのレコード数を
        「total」というフィールド名で抽出]
+--------+-------+
| name   | total |
+--------+-------+
| 前田   |     1 |
| 大島   |     1 |
| 高橋   |     5 |
| 指原   |     2 |
| 山本   |     1 |
+--------+-------+
5 rows in set (0.00 sec)

mysql>
mysql> [「posts」テーブルと「users」テーブルを
        「user_id」をキーとして内部結合し
        「user_id」が「3」または、「4」のレコードの
        「id(postsテーブル)」、「title」、「content」、「name」フィールドを
        「created」が新しい順に5件抽出]
+----+-----------------------------------+-----------------------------------------------------------------------------------------------------------+--------+
| id | title                             | content                                                                                                   | name   |
+----+-----------------------------------+-----------------------------------------------------------------------------------------------------------+--------+
| 10 | 限界です                          | こんにちは、もうブログを続けるのは限界です。                                                              | 高橋   |
|  9 | また、行っちゃいました            | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 指原   |
|  7 | おいしいお店発見!                | こんにちは、おいしいパスタのお店を発見しました。                                                          | 指原   |
|  6 | また、空いちゃいました            | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 高橋   |
|  5 | 久しぶりの投稿                    | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 高橋   |
+----+-----------------------------------+-----------------------------------------------------------------------------------------------------------+--------+
5 rows in set (0.00 sec)

mysql>
mysql> [「view2」というビューを作成し、
        「posts」テーブルと「users」テーブルを「user_id」をキーとして内部結合し
        「posts」テーブルの全フィールドと「name」、「email」フィールドを抽出する条件を保存]
Query OK, 0 rows affected (0.01 sec)

mysql>
mysql> [「view2」というビューを「created」の新しい順で全てのレコードを表示]
+----+---------+-----------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+--------+---------------------+
| id | user_id | title                             | content                                                                                                   | created     | modified            | name   | email               |
+----+---------+-----------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+--------+---------------------+
| 10 |       3 | 限界です                          | こんにちは、もうブログを続けるのは限界です。                                                              | 2017-07-18 10:00:00 | 2017-07-18 10:00:00 | 高橋   | takahashi@dummy.com |
|  9 |       4 | また、行っちゃいました            | こんにちは、先日見つけた美味しいパスタのお店に、また行っちゃいました。                                    | 2017-07-17 10:00:00 | 2017-07-17 10:00:00 | 指原   | sashihara@dummy.jp  |
|  7 |       4 | おいしいお店発見!                | こんにちは、おいしいパスタのお店を発見しました。                                                          | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 | 指原   | sashihara@dummy.jp  |
|  8 |       5 | 一人旅してます                    | こんにちは。今、北海道にいてます。一人旅してます。                                                        | 2017-07-15 10:00:00 | 2017-07-15 10:00:00 | 山本   | yamamoto@dummy.net  |
|  6 |       3 | また、空いちゃいました            | お久しぶりです。またまた日が空いてしまいましたね。                                                        | 2017-05-31 10:00:00 | 2017-05-31 10:00:00 | 高橋   | takahashi@dummy.com |
|  5 |       3 | 久しぶりの投稿                    | お久しぶりです。ちょっと日が空いてしまいましたね。                                                        | 2017-05-01 10:00:00 | 2017-05-01 10:00:00 | 高橋   | takahashi@dummy.com |
|  4 |       3 | まだやってます                    | 1度、このブログをやめようと思いまいしたが、まだやることにしました。                                       | 2017-04-11 10:00:00 | 2017-04-11 10:00:00 | 高橋   | takahashi@dummy.com |
|  3 |       3 | そろそろ・・・                    | こんにちは、そろそろネタが尽きてきました。                                                                | 2017-04-09 10:00:00 | 2017-04-09 10:00:00 | 高橋   | takahashi@dummy.com |
|  2 |       1 | 2回目の投稿!                     | こんにちは、2回目のブログですね。ちゃんと続いてますよ。                                                   | 2017-04-08 10:00:00 | 2017-04-08 10:00:00 | 前田   | maeda@dummy.com     |
|  1 |       2 | ブログ始めました                  | ついに、ブログを始めました。毎日更新するので楽しみにしてくださいね。                                      | 2017-04-07 10:00:00 | 2017-04-07 10:00:00 | 大島   | oshima@dummy.com    |
+----+---------+-----------------------------------+-----------------------------------------------------------------------------------------------------------+---------------------+---------------------+--------+---------------------+
10 rows in set (0.01 sec)

mysql>
mysql> [「view2」というビューを削除]
Query OK, 0 rows affected (0.00 sec)

mysql> 
解答例
chapter14/training.sql
-- 「posts」テーブルと「users」テーブルを「user_id」をキーとして内部結合し
-- 「title」フィールドと「name」フィールドのレコードを抽出
select p.title, u.name
  from posts as p join users as u
  on p.user_id = u.id;

-- 「posts」テーブルと「users」テーブルを「user_id」をキーとして内部結合し
-- 「name」フィールドと「user_id」ごとのレコード数を「total」というフィールド名で抽出
select u.name, count(*) as total
  from posts as p join users as u
  on p.user_id = u.id
  group by p.user_id;

-- 「posts」テーブルと「users」テーブルを「user_id」をキーとして内部結合し
-- 「user_id」が「3」または、「4」のレコードの
-- 「id(postsテーブル)」、「title」、「content」、「name」フィールドを
-- 「created」が新しい順に5件抽出
select p.id, p.title, p.content, u.name
  from posts as p join users as u
  on p.user_id = u.id
  where p.user_id in(3,4)
  order by p.created desc
  limit 5;

-- 「view2」というビューを作成し、
-- 「posts」テーブルと「users」テーブルを「user_id」をキーとして内部結合し
-- 「posts」テーブルの全フィールドと「name」、「email」フィールドを抽出する条件を保存
create view view2
  as
    select p.*, u.name, u.email
      from posts as p join users as u
      on p.user_id = u.id;

-- 「view2」というビューを「created」の新しい順で全てのレコードを表示
select * from view2 order by created desc;

-- 「view2」というビューを削除
drop view view2;

解答例は全問題のチェックボックスが on になるとご覧いただけます。

まとめ テーブルを結合すれば、
様々なデータを寄せ集めれる。

テーブルの結合には、内部結合外部結合など、様々なテーブルの結合方法がある。

  • キーが一致したレコードのみを抽出する結合を内部結合という
  • キーが一致しないレコードも表示するには、外部結合を使う
  • SELECT文の検索条件はビューに保存できる