「データベースが使えるようになりたい」と言われたので書いた
ある日うちの奥さん(エンジニアではない)から、「データベースが使えるようになりたいから教えてほしい」と相談を受けた。
一口にデータベースと言ってもいくつかあるので詳細を聞いてみると、彼女が意欲を示している「データベース」とは MySQL や PostgreSQL のこと*1で、今の職場に残されたレガシーなデータベースから古い情報を取り出すのに使うとのことだった。MySQL や PostgreSQL などのデータベース*2にはいくつかの機能があるが、情報の取り出しだけができればとりあえずは良いらしい。とはいえ「データベース使えますよ」と自信を持って言うために、情報の追加や更新、削除もできるようになっておきたい、ということだった。
そこで、そもそもデータベースはどんなもので、どういうことができるのか、どうすればできるのかを以下に簡単にまとめてみる。以下は奥さん向けに書いたものなので、普段エンジニア以外が耳慣れない言葉などはなるべく一度説明してから登場させるか、一度並べてから説明を後述することにする。ではいってみよう。
- 使う側にとっての「データベース」って何だろう
- 使うための用意
- 管理人と話そう
- 建物に入ろう
- 建物から帰ろう
- 建物の中でできること
- SQLコマンド
- MySQLコマンド
- コマンドを知る前に
- コマンドの説明をする前に本棚を作ろう
- コマンドを知ろう
- 定義済みのデータベースを一覧取得する(SHOW DATABASES)
- 操作したいデータベースを選ぶ(USE データベース名)
- 定義済みのテーブルを一覧取得する(SHOW TABLES)
- 定義済みのテーブルひとつを確認する(DESC テーブル名)
- テーブルの中から全カラムの情報を取得する(SELECT * FROM テーブル名)
- テーブルの中から特定のカラムの情報を取得する(SELECT カラム名 FROM テーブル名)
- テーブルの中から指定件数のデータを取得する(SELECT カラム名 FROM テーブル名 LIMIT 件数)
- テーブルの中から指定条件に完全一致するデータを取得する(SELECT カラム名 FROM テーブル名 WHERE カラム名 = '合致させたい内容')
- テーブルの中から指定条件に部分一致するデータを取得する(SELECT カラム名 FROM テーブル名 WHERE カラム名 LIKE '合致させたい内容')
- テーブルの中から複数条件のすべてに一致するデータを取得する(SELECT カラム名 FROM テーブル名 WHERE 条件 AND 条件)
- テーブルの中から複数条件のいずれかまたは両方に一致するデータを取得する(SELECT カラム名 FROM テーブル名 WHERE 条件 OR 条件)
- テーブルの取得結果をカラムの内容で並び替える(SELECT カラム名 FROM テーブル名 ORDER BY カラム名 昇順または降順)
- テーブルの取得条件に以上、以下を使う(SELECT カラム名 FROM テーブル名 WHERE カラム名 >= 数値 OR カラム名 <= 数値)
- テーブルの全件数を取得する(SELECT COUNT(*) FROM テーブル名)
- テーブルの内容を特定のカラムの内容でグループ分けする(SELECT * FROM テーブル名 GROUP BY カラム名)
- 指定されたカラムの最大値、最小値を取得する(SELECT MAX(カラム名), MIN(カラム名) FROM テーブル名 GROUP BY カラム名)
- 指定されたカラムに登録されている内容の合計値を取得する(SELECT SUM(カラム名) FROM テーブル名)
- 指定されたカラムに登録されている内容の文字数を取得する(SELECT LENGTH(カラム名) FROM テーブル名)
- 指定されたカラムに登録されている内容を重複を取り除いて表示する(SELECT DISTINCT カラム名 FROM テーブル名)
- 複数のカラムの内容や文字列を結合して結果に含める(SELECT CONCAT(文字列やカラム名, 文字列やカラム名, ...) FROM テーブル名)
- 取得結果に別名をつける(SELECT 取得結果 AS 別名)
- ふたつのテーブルを組み合わせて結果を取得する
- テーブルにデータを追加する(INSERT INTO テーブル名 ( カラム名 ) VALUES ( データ ))
- テーブルのデータを更新する(UPDATE テーブル名 SET カラム名 = 変更内容 WHERE 条件)
- データを削除する(DELETE FROM テーブル名 WHERE 条件)
- データベースの定義(CREATE DATABASE データベース名)
- データベース定義文の確認(SHOW CREATE DATABASE データベース名)
- データベースの削除(DROP DATABASE データベース名)
- テーブルの定義(CREATE TABLE テーブル名...)
- テーブルの定義文を確認する(SHOW CREATE TABLE テーブル名)
- テーブルの削除(DROP TABLE テーブル名)
- テーブルにカラムを追加する(ALTER TABLE テーブル名 ADD COLUMN カラム名 カラム設定)
- テーブルからカラムを削除する(ALTER TABLE テーブル名 DROP COLUMN カラム名)
- コマンドを入力していて起こりがちなトラブル
- 終わりに
使う側にとっての「データベース」って何だろう
データベースの用途を一言で表すなら、「情報を取り出しやすいように整理して置いておける場所」*3だと思う。言わば、たくさん本をしまっておいてすぐに取り出すことのできるとても便利な本棚と、その本棚から本を取ってきてくれる超素早い管理人がセットになったようなもの。
データベースを構成するもの
- 本棚
- 管理人(めちゃくちゃ素早い。本棚の目録を持っている)
※ 目録がなかったので代わりに金棒になりました。
「データベースってエクセルとかスプレッドシートと同じようなもんなんじゃないの」という話を聞くことがあるのは、その発言をする人がExcelやGoogle Spreadsheetsを「情報を取り出しやすいように整理して置いておける場所」として使っているからで、要するにその人にとっての用途が同じだから「同じようなもん」だと感じるのだろうと思う。ExcelやGoogle Spreadsheetsでできるように、「検索」機能を使って文字の部分一致検索をしたり、特定のセルの内容に一致する他のシートの行を引っ張ってきたりということは、データベースでもできる。
使うための用意
データベースを使うためには、以下のものが必要になる。すでにデータベースが用意されている環境なら、以下の中から不足しているものだけを用意しよう。説明していない言葉が出てくるが、ここでは列記するだけで後で説明する。
- データベースサーバ
- クライアント
データベースサーバとクライアントって何?
『データベースサーバ』は上でのたとえで言うところの、本棚と管理者と、それらがいる建物のことを指す。『クライアント』はあなたの召使いで、あなたが「あの本取ってきて」と頼むとデータベースサーバに出かけていき、管理者に「あの本取ってきて」と話しかけ、そこで本を見てその内容のコピーを取り、あなたのところまで持ち帰ってくる。他の人が見に来る可能性があるので、本そのものを持ち帰ることはできない。
この仕組みは、インターネットで見ているWebサイトと同じだと考えることもできる。あなたが今使っているブラウザ(ChromeやSafariやIEやEdgeなど)が『クライアント』で、彼に*4「 http://mizunokura.hatenablog.com/
という場所に書かれている内容を取ってきて」と頼むと、その場所にある建物まで出かけて行き、そこにいる管理者に見せてくれるよう話しかけ、見せてもらった内容のコピーを取り、あなたのところまで持ち帰ってくる。
データベースサーバの用意
すでにどこかにあることがわかっている場合
その場合、以下の情報を集める必要がある。ここでも先に列記してから後で説明する。
- データベースサーバの種別
- アドレス
- 認証情報
- ポート番号
データベースサーバの種別
データベースサーバにはいくつかの種類がある。
その他にもたくさんの種類があるが、市場シェア割合が高いのはこの4つ。それぞれに異なるクライアントを使用するので、種別を知っておく必要がある。こればっかりは聞くしかないので識者に質問しよう。種別が判明したら「MySQL クライアント インストール Mac」などで検索し、自分のパソコンにクライアントをインストールしよう。
アドレス
建物で例えるなら住所のこと。クライアントが出かけて行く先。IPアドレス(192.168.1.1 とか)だったり、ホストアドレス(db0001.local とか)だったりする。これも聞くしかないので聞こう。
認証情報
クライアントが建物に入っていくための名前(ユーザー名)とパスワード。これも聞くしかないので聞こう。
ポート番号
じつは、建物にはたくさん出入り口が用意されている。しかしながらセキュリティを確保するために、指定された出入り口以外を使うことはできないことになっている。MySQL の場合、初期設定では 3306 番の出入り口を使用する。これも聞くしかないので聞こう。聞いて「わからない」と言われたら、たいてい 3306 番だと思っておそらく問題ない。
とりあえず自分が使えればいい場合
その場合は、自分のパソコンの中に建物を建てて本棚を置いて管理人を連れてくることができる。データベースサーバの種別を決め、パソコンにインストールしよう(ググろう)。
みんなで使いたい場合
その場合も「自分が使えればいい場合」と考え方はほとんど同じだが、自分のパソコンの中ではなく、みんなが使うことのできる共通の場所に建物を建てる必要がある。その方法などなどを説明し始めると話が逸れるので割愛する。
クライアントの用意
上述の通り、データベースサーバの種別ごとに異なるので、種別を調べてから「MySQL クライアント インストール Mac」などで検索し、自分のパソコンにクライアントをインストールしよう。
管理人と話そう
データベースサーバとクライアントの準備ができたら、さっそく建物の中にいる管理人に挨拶してみよう。都合上ここからは MySQL に絞って説明していく。
建物に入ろう
データベースサーバという建物の中に入っていくためには、上述の「アドレス」と「認証情報」と「ポート番号」とを使う必要がある。コマンドラインクライアント(黒背景に白文字の画面で使用するクライアント)の場合、ターミナルに以下を入力($
は入力しない)して、エンターキーを押して実行する。
$ mysql -u ユーザー名 -h アドレス --port ポート番号 -p
このような、パソコンに対する命令文を「コマンド」と呼ぶ。
また、上記のコマンドのポート番号については初期設定で3306になっているので省略できる。さらに、パスワードが設定されていない場合にも省略でき、自分のパソコンの中に建物を建てた場合アドレスも省略できるので、以下の内容で実行することができる。
$ mysql -u ユーザー名
自分でデータベースサーバをインストールした場合、ユーザー名は、とくに変更していないのであれば root
になっている。
例えば以下のような表示が出てくれば、建物に入ること(ログイン)に成功している。
$ mysql -uroot Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 Server version: 5.7.21 Homebrew Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
上の mysql>
の部分がクライアントの待機状態を示す文字列で、「管理人になんて言ってきましょうか」と自分に聞いてきてると考えると良いかもしれない。
パスワードの入力を促される場合
実行時に -p
を付けている場合、以下のようにパスワードの入力を促される場合がある。パスワードを入力しよう。画面に入力している文字が何も表示されないが、そのまま入力してエンターキーを押せば問題ない。
$ mysql -u ユーザー名 -p Enter password:
パスワードを間違えていると以下のようなエラーメッセージが表示される。
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
また、以下のようにパスワードをコマンドに含めてしまうこともできる。
$ mysql -u ユーザー名 -pパスワード
MySQL サーバが起動していない場合
以下のようなエラーメッセージが出る場合、MySQL データベースサーバが起動してない。例えるなら、建物も本棚も管理人もいない状態である。
$ mysql -uroot ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
Mac で homebrew を使ってインストールした場合、以下のコマンドを使って起動することができる。
$ brew services start mysql
建物から帰ろう
いつでもクライアントを終了できるように、その方法を確認しておこう。mysql>
の表示に続けて quit
と入力し、エンターキーを押せば良い。
mysql> quit
また、 Ctrl+D キー
でもクライアントを即座に終了することができる。
建物の中でできること
MySQL データベースサーバでは、大きく分けてふたつのことができる。どちらもクライアントが管理人に対して話しかけることで効果を発揮する。
SQLコマンド
SQLコマンドとは、データベースを操作する際に使用するために作られた命令文の集合*5で、最初のバージョンが発表されてから各データベースサーバがそれぞれに取り入れ、さらに独自の拡張を行ってきたもの。あまりにも各データベースサーバごとに異なってしまうのを防ぐために作られた標準統一規格が存在するので、基本的にはある程度共通しているが、異なっている部分もある。
大きく分けて、以下の操作ができる。カッコ内は本棚の例えをした場合のイメージ。
- データ定義(本棚や、本棚に置く内容を決めたりする)
- データ操作(本棚に本を置いたり、削除したり、上書きしたりする)
- データ制御(建物にはいれる人を決めたり、本棚の内容を変えるのを制限したりする)
MySQLコマンド
SQLコマンドに定義されていないものの、各データベースサーバが必要に応じて追加した独自の命令文の集合。それぞれ独自のコマンドなので、データベースサーバごとに大きく異なっている。「MySQLコマンド」という言葉は筆者が名付けただけなので、一般には通じないことに注意。
コマンドを知る前に
ここから各コマンドについて説明するが、その前に知っておくべきこと、用意しておくべきことを説明する。
コマンドの説明の前に知っておくべきこと
データベースサーバ内では、以下の概念を取り扱う。
- データベース
- テーブル
- カラム
- ユーザー
データベース
「情報を取り扱うための入れ物の入れ物」。本棚の例えで言うところの、管理人が管理しているたくさんの本棚の群れのこと。Excelなら1つのxlsxファイル。Google Spreadsheetsなら1つのスプレッドシート。
テーブル
「情報を取り扱うための入れ物」。本棚の例えで言うところの、たくさんの本棚のうちのひとつ。Excelなら1つのxlsxファイルの中の1枚のシート。Google Spreadsheetsなら1つのスプレッドシートの中の1枚のシート。
カラム
「入れ物の中の間仕切りと、仕切られた空間につけられた名前」。本棚の例えで言うところの、「書名」や「著者名」といった分類するための情報区分。ExcelやGoogle Spreadsheetsなら、たいてい1行目に記載するその列の名前。
ユーザー
「操作をする人」。本棚の例えで言うところの、建物にはいる人の名前とパスワード。Excelなら操作している自分自身。Google Spreadsheetsなら、Google にログインするアカウント。
コマンドの説明をする前に本棚を作ろう
コマンドの説明をするにあたって、手元に動作を確認する環境があると理解しやすくなる。MySQL の場合は公式にデータベースとテーブルのセットを用意してくれているので、ダウンロードして使うと良い。
参照: https://dev.mysql.com/doc/index-other.html
ダウンロードしたZIPファイルを解凍して作成された world.sql
を mysql クライアントに渡してやると、世界の国々の人口や首都、都市の人口などのデータ、言語などが入ったデータベースを作成してくれる。
$ mysql -u ユーザー名 < ./world.sql
※ ./world.sql
の部分は各自ダウンロードしたファイルがある場所までのディレクトリパスを入力する。もしそれが Mac のダウンロードフォルダなら、
$ mysql -u ユーザー名 < ~/Downloads/world.sql
とすることで作成できる。
コマンドを知ろう
ここからコマンドについて説明していく。基本的にエンターキーが押されるまでクライアントは管理人に話しかけに行かない。また、基本的に末尾に ;
(セミコロン)や ¥G
が付いていなければ、管理人はコマンド入力がまだ続いていると判断して、何もしない((USE
など一部コマンドは除く))。以下ではコマンドを大文字表記しているが、小文字でも問題ない。
定義済みのデータベースを一覧取得する(SHOW DATABASES)
データベースサーバ内のデータベース(建物内にある本棚群)の一覧を取ってきてもらい、見るMySQLコマンド。
mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | world | +--------------------+ 5 rows in set (0.00 sec)
ここで表示されたのは、データベースの名前だ。 world
以外の4つは、MySQL データベースサーバインストール時から用意されているデータベース管理用のもの(管理人が使うもの)なので、直接触る必要はない。
操作したいデータベースを選ぶ(USE データベース名)
操作したい本棚の名前を指定するMySQLコマンド。
mysql> use world; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed
本棚を指定しないまま、先に本棚を指定しているべきコマンドを入力した場合、以下のエラーになる。
mysql> show tables; ERROR 1046 (3D000): No database selected
ログイン時(建物に入る時)に以下のようにすることで、USE データベース名
を入力することなくデータベースを指定することもできる。
$ mysql -u ユーザー名 -h アドレス --port ポート番号 -p データベース名 # または $ mysql -u ユーザー名 データベース名 # など
定義済みのテーブルを一覧取得する(SHOW TABLES)
データベース内のテーブル(本棚群の中の本棚)の一覧を取ってきてもらい、見るMySQLコマンド。
mysql> SHOW TABLES; +-----------------+ | Tables_in_world | +-----------------+ | city | | country | | countrylanguage | +-----------------+ 3 rows in set (0.00 sec)
定義済みのテーブルひとつを確認する(DESC テーブル名)
データベース内のテーブルひとつの情報を取ってきてもらい、見るMySQLコマンド。ここでは、上で確認した中にある country
テーブルの情報を確認しよう。
mysql> DESC country; +----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+ | Code | char(3) | NO | PRI | | | | Name | char(52) | NO | | | | | Continent | enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') | NO | | Asia | | | Region | char(26) | NO | | | | | SurfaceArea | float(10,2) | NO | | 0.00 | | | IndepYear | smallint(6) | YES | | NULL | | | Population | int(11) | NO | | 0 | | | LifeExpectancy | float(3,1) | YES | | NULL | | | GNP | float(10,2) | YES | | NULL | | | GNPOld | float(10,2) | YES | | NULL | | | LocalName | char(45) | NO | | | | | GovernmentForm | char(45) | NO | | | | | HeadOfState | char(60) | YES | | NULL | | | Capital | int(11) | YES | | NULL | | | Code2 | char(2) | NO | | | | +----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+ 15 rows in set (0.01 sec)
Field
はカラムに付けられた名前。 Type
はカラムに入れられるデータの種類。Null
はそのカラムにnull(空のデータ)が入ることを許容するかどうか。Key
はそのカラムの一意制約(後述)の情報。Default
はそのカラムに値を指定しなかった場合に自動的で入る値。Extra
は付随情報。
また Field
には、日本語を使うこともできる。
テーブルの中から全カラムの情報を取得する(SELECT * FROM テーブル名)
テーブルの中に定義されている全カラムの情報を取得するコマンド。FROM
のあとに続けて、データを取ってきてほしいテーブル名を指定する。ここでは、上で情報を確認した country
テーブルの内容を取得してみよう。
mysql> SELECT * FROM country; +------+----------------------------------------------+---------------+---------------------------+-------------+-----------+------------+----------------+------------+------------+----------------------------------------------+----------------------------------------------+--------------------------------------+---------+-------+ | Code | Name | Continent | Region | SurfaceArea | IndepYear | Population | LifeExpectancy | GNP | GNPOld | LocalName | GovernmentForm | HeadOfState | Capital | Code2 | +------+----------------------------------------------+---------------+---------------------------+-------------+-----------+------------+----------------+------------+------------+----------------------------------------------+----------------------------------------------+--------------------------------------+---------+-------+ | ABW | Aruba | North America | Caribbean | 193.00 | NULL | 103000 | 78.4 | 828.00 | 793.00 | Aruba | Nonmetropolitan Territory of The Netherlands | Beatrix | 129 | AW | | AFG | Afghanistan | Asia | Southern and Central Asia | 652090.00 | 1919 | 22720000 | 45.9 | 5976.00 | NULL | Afganistan/Afqanestan | Islamic Emirate | Mohammad Omar | 1 | AF | | AGO | Angola | Africa | Central Africa | 1246700.00 | 1975 | 12878000 | 38.3 | 6648.00 | 7984.00 | Angola | Republic | José Eduardo dos Santos | 56 | AO | (中略) | ZAF | South Africa | Africa | Southern Africa | 1221037.00 | 1910 | 40377000 | 51.1 | 116729.00 | 129092.00 | South Africa | Republic | Thabo Mbeki | 716 | ZA | | ZMB | Zambia | Africa | Eastern Africa | 752618.00 | 1964 | 9169000 | 37.2 | 3377.00 | 3922.00 | Zambia | Republic | Frederick Chiluba | 3162 | ZM | | ZWE | Zimbabwe | Africa | Eastern Africa | 390757.00 | 1980 | 11669000 | 37.8 | 5951.00 | 8670.00 | Zimbabwe | Republic | Robert G. Mugabe | 4068 | ZW | +------+----------------------------------------------+---------------+---------------------------+-------------+-----------+------------+----------------+------------+------------+----------------------------------------------+----------------------------------------------+--------------------------------------+---------+-------+ 239 rows in set (0.01 sec)
239行もあるので、画面が文字で埋まってしまい大変なことになる。そこで、ひとまず名前だけを取ってきてみたい。
テーブルの中から特定のカラムの情報を取得する(SELECT カラム名 FROM テーブル名)
DESC テーブル名
で確認したカラム名(Field
の部分)を指定することで、そのカラムの情報だけを取ってくることができる。
mysql> SELECT Name FROM country; +----------------------------------------------+ | Name | +----------------------------------------------+ | Aruba | | Afghanistan | | Angola | (中略) | South Africa | | Zambia | | Zimbabwe | +----------------------------------------------+ 239 rows in set (0.00 sec)
また、カラム名はカンマ(,
)で区切ることで複数指定することもできる。また、全カラム取得時に指定したアスタリスク(*
)は、じつは「全カラム」という意味を持っている。
mysql> SELECT Code, Name FROM country; +------+----------------------------------------------+ | Code | Name | +------+----------------------------------------------+ | ABW | Aruba | | AFG | Afghanistan | | AGO | Angola | (中略) | ZAF | South Africa | | ZMB | Zambia | | ZWE | Zimbabwe | +------+----------------------------------------------+ 239 rows in set (0.00 sec)
これで多少見やすくはなったが、行数が多いのでまだすこしわかりにくいと思う。そこで、今度は指定した件数だけを取ってきてみたい。
テーブルの中から指定件数のデータを取得する(SELECT カラム名 FROM テーブル名 LIMIT 件数)
LIMIT 件数
を指定することで、指定件数のデータだけを取ってくることができる。
mysql> SELECT Code,Name FROM country LIMIT 10; +------+----------------------+ | Code | Name | +------+----------------------+ | ABW | Aruba | | AFG | Afghanistan | | AGO | Angola | | AIA | Anguilla | | ALB | Albania | | AND | Andorra | | ANT | Netherlands Antilles | | ARE | United Arab Emirates | | ARG | Argentina | | ARM | Armenia | +------+----------------------+ 10 rows in set (0.00 sec)
これで画面が平和になった。しかし、今度は11行目以降が見えなくなってしまった。次の10件を取ってきてもらうには、 OFFSET 件数
を末尾でさらに指定する。
mysql> SELECT Code,Name FROM country LIMIT 10 OFFSET 10; +------+-----------------------------+ | Code | Name | +------+-----------------------------+ | ASM | American Samoa | | ATA | Antarctica | | ATF | French Southern territories | | ATG | Antigua and Barbuda | | AUS | Australia | | AUT | Austria | | AZE | Azerbaijan | | BDI | Burundi | | BEL | Belgium | | BEN | Benin | +------+-----------------------------+ 10 rows in set (0.00 sec)
同様に、次の21行目以降を見るためには OFFSET 20
を指定すれば良い。これで少しずつ見ることができるようなった。では、OFFSET の件数を変えて、日本(Japan)の情報だけを見てみよう。
mysql> SELECT Code,Name FROM country LIMIT 10 OFFSET 100; +------+--------------------------------+ | Code | Name | +------+--------------------------------+ | IOT | British Indian Ocean Territory | | IRL | Ireland | | IRN | Iran | | IRQ | Iraq | | ISL | Iceland | | ISR | Israel | | ITA | Italy | | JAM | Jamaica | | JOR | Jordan | | JPN | Japan | +------+--------------------------------+ 10 rows in set (0.00 sec)
…あった。Japan は110行目にようやく見つかった。しかし、今回のように239件しかないテーブルならともかく、たとえば10万件あるテーブルの中から特定のデータ1件を見つけるために、OFFSET 10、20、40…と繰り返すのは手間がかかりすぎる。そこで、日本のように名前がわかっている国のデータを、名前で探せるようにしたい。
テーブルの中から指定条件に完全一致するデータを取得する(SELECT カラム名 FROM テーブル名 WHERE カラム名 = '合致させたい内容')
WHERE
に続けて、カラム名と合致させたい内容を指定することで、条件に合うデータ行だけを取得することができる。ここでは国名(Name)が日本(Japan)になっているデータを取ってきてほしいので、WHERE Name = 'Japan'
と指定する。
mysql> SELECT * FROM country WHERE Name = 'Japan'; +------+-------+-----------+--------------+-------------+-----------+------------+----------------+------------+------------+--------------+-------------------------+-------------+---------+-------+ | Code | Name | Continent | Region | SurfaceArea | IndepYear | Population | LifeExpectancy | GNP | GNPOld | LocalName | GovernmentForm | HeadOfState | Capital | Code2 | +------+-------+-----------+--------------+-------------+-----------+------------+----------------+------------+------------+--------------+-------------------------+-------------+---------+-------+ | JPN | Japan | Asia | Eastern Asia | 377829.00 | -660 | 126714000 | 80.7 | 3787042.00 | 4192638.00 | Nihon/Nippon | Constitutional Monarchy | Akihito | 1532 | JP | +------+-------+-----------+--------------+-------------+-----------+------------+----------------+------------+------------+--------------+-------------------------+-------------+---------+-------+ 1 row in set (0.00 sec)
無事取ってこれた。しかし横長になってしまってすこし見づらい。その場合は、末尾の ;
を ¥G
に変えることで、横並びに表示されているデータを縦並びに表示することができる。
mysql> SELECT * FROM country WHERE Name = 'Japan'\G *************************** 1. row *************************** Code: JPN Name: Japan Continent: Asia Region: Eastern Asia SurfaceArea: 377829.00 IndepYear: -660 Population: 126714000 LifeExpectancy: 80.7 GNP: 3787042.00 GNPOld: 4192638.00 LocalName: Nihon/Nippon GovernmentForm: Constitutional Monarchy HeadOfState: Akihito Capital: 1532 Code2: JP 1 row in set (0.00 sec)
では、同じように大陸(Continent)がアジア(Asia)になっている国の一覧を取ってきてみよう。
mysql> SELECT * FROM country WHERE Continent = 'Asia'\G (中略) *************************** 51. row *************************** Code: YEM Name: Yemen Continent: Asia Region: Middle East SurfaceArea: 527968.00 IndepYear: 1918 Population: 18112000 LifeExpectancy: 59.8 GNP: 6041.00 GNPOld: 5729.00 LocalName: Al-Yaman GovernmentForm: Republic HeadOfState: Ali Abdallah Salih Capital: 1780 Code2: YE 51 rows in set (0.00 sec)
今度は逆に見辛くなってしまったので、横長にしてみる。
mysql> SELECT * FROM country WHERE Continent = 'Asia'; +------+----------------------+-----------+---------------------------+-------------+-----------+------------+----------------+------------+------------+----------------------------------------------+----------------------------------------+----------------------------------+---------+-------+ | Code | Name | Continent | Region | SurfaceArea | IndepYear | Population | LifeExpectancy | GNP | GNPOld | LocalName | GovernmentForm | HeadOfState | Capital | Code2 | +------+----------------------+-----------+---------------------------+-------------+-----------+------------+----------------+------------+------------+----------------------------------------------+----------------------------------------+----------------------------------+---------+-------+ | AFG | Afghanistan | Asia | Southern and Central Asia | 652090.00 | 1919 | 22720000 | 45.9 | 5976.00 | NULL | Afganistan/Afqanestan | Islamic Emirate | Mohammad Omar | 1 | AF | | ARE | United Arab Emirates | Asia | Middle East | 83600.00 | 1971 | 2441000 | 74.1 | 37966.00 | 36846.00 | Al-Imarat al-´Arabiya al-Muttahida | Emirate Federation | Zayid bin Sultan al-Nahayan | 65 | AE | | ARM | Armenia | Asia | Middle East | 29800.00 | 1991 | 3520000 | 66.4 | 1813.00 | 1627.00 | Hajastan | Republic | Robert Kotšarjan | 126 | AM | | AZE | Azerbaijan | Asia | Middle East | 86600.00 | 1991 | 7734000 | 62.9 | 4127.00 | 4100.00 | Azärbaycan | Federal Republic | Heydär Äliyev | 144 | AZ | | BGD | Bangladesh | Asia | Southern and Central Asia | 143998.00 | 1971 | 129155000 | 60.2 | 32852.00 | 31966.00 | Bangladesh | Republic | Shahabuddin Ahmad | 150 | BD | | BHR | Bahrain | Asia | Middle East | 694.00 | 1971 | 617000 | 73.0 | 6366.00 | 6097.00 | Al-Bahrayn | Monarchy (Emirate) | Hamad ibn Isa al-Khalifa | 149 | BH | | BRN | Brunei | Asia | Southeast Asia | 5765.00 | 1984 | 328000 | 73.6 | 11705.00 | 12460.00 | Brunei Darussalam | Monarchy (Sultanate) | Haji Hassan al-Bolkiah | 538 | BN | | BTN | Bhutan | Asia | Southern and Central Asia | 47000.00 | 1910 | 2124000 | 52.4 | 372.00 | 383.00 | Druk-Yul | Monarchy | Jigme Singye Wangchuk | 192 | BT | | CHN | China | Asia | Eastern Asia | 9572900.00 | -1523 | 1277558000 | 71.4 | 982268.00 | 917719.00 | Zhongquo | People'sRepublic | Jiang Zemin | 1891 | CN | | CYP | Cyprus | Asia | Middle East | 9251.00 | 1960 | 754700 | 76.7 | 9333.00 | 8246.00 | Kýpros/Kibris | Republic | Glafkos Klerides | 2430 | CY | | GEO | Georgia | Asia | Middle East | 69700.00 | 1991 | 4968000 | 64.5 | 6064.00 | 5924.00 | Sakartvelo | Republic | Eduard Ševardnadze | 905 | GE | | HKG | Hong Kong | Asia | Eastern Asia | 1075.00 | NULL | 6782000 | 79.5 | 166448.00 | 173610.00 | Xianggang/Hong Kong | Special Administrative Region of China | Jiang Zemin | 937 | HK | | IDN | Indonesia | Asia | Southeast Asia | 1904569.00 | 1945 | 212107000 | 68.0 | 84982.00 | 215002.00 | Indonesia | Republic | Abdurrahman Wahid | 939 | ID | | IND | India | Asia | Southern and Central Asia | 3287263.00 | 1947 | 1013662000 | 62.5 | 447114.00 | 430572.00 | Bharat/India | Federal Republic | Kocheril Raman Narayanan | 1109 | IN | | IRN | Iran | Asia | Southern and Central Asia | 1648195.00 | 1906 | 67702000 | 69.7 | 195746.00 | 160151.00 | Iran | Islamic Republic | Ali Mohammad Khatami-Ardakani | 1380 | IR | | IRQ | Iraq | Asia | Middle East | 438317.00 | 1932 | 23115000 | 66.5 | 11500.00 | NULL | Al-´Iraq | Republic | Saddam Hussein al-Takriti | 1365 | IQ | | ISR | Israel | Asia | Middle East | 21056.00 | 1948 | 6217000 | 78.6 | 97477.00 | 98577.00 | Yisra’el/Isra’il | Republic | Moshe Katzav | 1450 | IL | | JOR | Jordan | Asia | Middle East | 88946.00 | 1946 | 5083000 | 77.4 | 7526.00 | 7051.00 | Al-Urdunn | Constitutional Monarchy | Abdullah II | 1786 | JO | | JPN | Japan | Asia | Eastern Asia | 377829.00 | -660 | 126714000 | 80.7 | 3787042.00 | 4192638.00 | Nihon/Nippon | Constitutional Monarchy | Akihito | 1532 | JP | | KAZ | Kazakstan | Asia | Southern and Central Asia | 2724900.00 | 1991 | 16223000 | 63.2 | 24375.00 | 23383.00 | Qazaqstan | Republic | Nursultan Nazarbajev | 1864 | KZ | | KGZ | Kyrgyzstan | Asia | Southern and Central Asia | 199900.00 | 1991 | 4699000 | 63.4 | 1626.00 | 1767.00 | Kyrgyzstan | Republic | Askar Akajev | 2253 | KG | | KHM | Cambodia | Asia | Southeast Asia | 181035.00 | 1953 | 11168000 | 56.5 | 5121.00 | 5670.00 | Kâmpuchéa | Constitutional Monarchy | Norodom Sihanouk | 1800 | KH | | KOR | South Korea | Asia | Eastern Asia | 99434.00 | 1948 | 46844000 | 74.4 | 320749.00 | 442544.00 | Taehan Min’guk (Namhan) | Republic | Kim Dae-jung | 2331 | KR | | KWT | Kuwait | Asia | Middle East | 17818.00 | 1961 | 1972000 | 76.1 | 27037.00 | 30373.00 | Al-Kuwayt | Constitutional Monarchy (Emirate) | Jabir al-Ahmad al-Jabir al-Sabah | 2429 | KW | | LAO | Laos | Asia | Southeast Asia | 236800.00 | 1953 | 5433000 | 53.1 | 1292.00 | 1746.00 | Lao | Republic | Khamtay Siphandone | 2432 | LA | | LBN | Lebanon | Asia | Middle East | 10400.00 | 1941 | 3282000 | 71.3 | 17121.00 | 15129.00 | Lubnan | Republic | Émile Lahoud | 2438 | LB | | LKA | Sri Lanka | Asia | Southern and Central Asia | 65610.00 | 1948 | 18827000 | 71.8 | 15706.00 | 15091.00 | Sri Lanka/Ilankai | Republic | Chandrika Kumaratunga | 3217 | LK | | MAC | Macao | Asia | Eastern Asia | 18.00 | NULL | 473000 | 81.6 | 5749.00 | 5940.00 | Macau/Aomen | Special Administrative Region of China | Jiang Zemin | 2454 | MO | | MDV | Maldives | Asia | Southern and Central Asia | 298.00 | 1965 | 286000 | 62.2 | 199.00 | NULL | Dhivehi Raajje/Maldives | Republic | Maumoon Abdul Gayoom | 2463 | MV | | MMR | Myanmar | Asia | Southeast Asia | 676578.00 | 1948 | 45611000 | 54.9 | 180375.00 | 171028.00 | Myanma Pye | Republic | kenraali Than Shwe | 2710 | MM | | MNG | Mongolia | Asia | Eastern Asia | 1566500.00 | 1921 | 2662000 | 67.3 | 1043.00 | 933.00 | Mongol Uls | Republic | Natsagiin Bagabandi | 2696 | MN | | MYS | Malaysia | Asia | Southeast Asia | 329758.00 | 1957 | 22244000 | 70.8 | 69213.00 | 97884.00 | Malaysia | Constitutional Monarchy, Federation | Salahuddin Abdul Aziz Shah Alhaj | 2464 | MY | | NPL | Nepal | Asia | Southern and Central Asia | 147181.00 | 1769 | 23930000 | 57.8 | 4768.00 | 4837.00 | Nepal | Constitutional Monarchy | Gyanendra Bir Bikram | 2729 | NP | | OMN | Oman | Asia | Middle East | 309500.00 | 1951 | 2542000 | 71.8 | 16904.00 | 16153.00 | ´Uman | Monarchy (Sultanate) | Qabus ibn Sa´id | 2821 | OM | | PAK | Pakistan | Asia | Southern and Central Asia | 796095.00 | 1947 | 156483000 | 61.1 | 61289.00 | 58549.00 | Pakistan | Republic | Mohammad Rafiq Tarar | 2831 | PK | | PHL | Philippines | Asia | Southeast Asia | 300000.00 | 1946 | 75967000 | 67.5 | 65107.00 | 82239.00 | Pilipinas | Republic | Gloria Macapagal-Arroyo | 766 | PH | | PRK | North Korea | Asia | Eastern Asia | 120538.00 | 1948 | 24039000 | 70.7 | 5332.00 | NULL | Choson Minjujuui In´min Konghwaguk (Bukhan) | Socialistic Republic | Kim Jong-il | 2318 | KP | | PSE | Palestine | Asia | Middle East | 6257.00 | NULL | 3101000 | 71.4 | 4173.00 | NULL | Filastin | Autonomous Area | Yasser (Yasir) Arafat | 4074 | PS | | QAT | Qatar | Asia | Middle East | 11000.00 | 1971 | 599000 | 72.4 | 9472.00 | 8920.00 | Qatar | Monarchy | Hamad ibn Khalifa al-Thani | 2973 | QA | | SAU | Saudi Arabia | Asia | Middle East | 2149690.00 | 1932 | 21607000 | 67.8 | 137635.00 | 146171.00 | Al-´Arabiya as-Sa´udiya | Monarchy | Fahd ibn Abdul-Aziz al-Sa´ud | 3173 | SA | | SGP | Singapore | Asia | Southeast Asia | 618.00 | 1965 | 3567000 | 80.1 | 86503.00 | 96318.00 | Singapore/Singapura/Xinjiapo/Singapur | Republic | Sellapan Rama Nathan | 3208 | SG | | SYR | Syria | Asia | Middle East | 185180.00 | 1941 | 16125000 | 68.5 | 65984.00 | 64926.00 | Suriya | Republic | Bashar al-Assad | 3250 | SY | | THA | Thailand | Asia | Southeast Asia | 513115.00 | 1350 | 61399000 | 68.6 | 116416.00 | 153907.00 | Prathet Thai | Constitutional Monarchy | Bhumibol Adulyadej | 3320 | TH | | TJK | Tajikistan | Asia | Southern and Central Asia | 143100.00 | 1991 | 6188000 | 64.1 | 1990.00 | 1056.00 | Toçikiston | Republic | Emomali Rahmonov | 3261 | TJ | | TKM | Turkmenistan | Asia | Southern and Central Asia | 488100.00 | 1991 | 4459000 | 60.9 | 4397.00 | 2000.00 | Türkmenostan | Republic | Saparmurad Nijazov | 3419 | TM | | TMP | East Timor | Asia | Southeast Asia | 14874.00 | NULL | 885000 | 46.0 | 0.00 | NULL | Timor Timur | Administrated by the UN | José Alexandre Gusmão | 1522 | TP | | TUR | Turkey | Asia | Middle East | 774815.00 | 1923 | 66591000 | 71.0 | 210721.00 | 189122.00 | Türkiye | Republic | Ahmet Necdet Sezer | 3358 | TR | | TWN | Taiwan | Asia | Eastern Asia | 36188.00 | 1945 | 22256000 | 76.4 | 256254.00 | 263451.00 | T’ai-wan | Republic | Chen Shui-bian | 3263 | TW | | UZB | Uzbekistan | Asia | Southern and Central Asia | 447400.00 | 1991 | 24318000 | 63.7 | 14194.00 | 21300.00 | Uzbekiston | Republic | Islam Karimov | 3503 | UZ | | VNM | Vietnam | Asia | Southeast Asia | 331689.00 | 1945 | 79832000 | 69.3 | 21929.00 | 22834.00 | Viêt Nam | Socialistic Republic | Trân Duc Luong | 3770 | VN | | YEM | Yemen | Asia | Middle East | 527968.00 | 1918 | 18112000 | 59.8 | 6041.00 | 5729.00 | Al-Yaman | Republic | Ali Abdallah Salih | 1780 | YE | +------+----------------------+-----------+---------------------------+-------------+-----------+------------+----------------+------------+------------+----------------------------------------------+----------------------------------------+----------------------------------+---------+-------+ 51 rows in set (0.00 sec)
このように、 =
で指定した内容に完全一致する行だけが取得できた。では、世界の中で、日本と同じように国名の先頭が 'J' で始まる国はいくつあるだろうか。
テーブルの中から指定条件に部分一致するデータを取得する(SELECT カラム名 FROM テーブル名 WHERE カラム名 LIKE '合致させたい内容')
=
の代わりにLIKE
を使うことで、完全一致ではなく部分一致でデータを探すことができる。指定したい箇所以外の文字はパーセント(%
)で表記する。たとえば「国名がJではじまる」であれば WHERE Name LIKE 'J%'
とし、「国名がnで終わる」であれば WHERE Name LIKE '%n'
とし、「国名の先頭と末尾以外がapa」であれば、 WHERE Name Like '%apa%'
と指定する。
mysql> SELECT * FROM country WHERE Name LIKE 'J%'; +------+---------+---------------+--------------+-------------+-----------+------------+----------------+------------+------------+--------------+-------------------------+--------------+---------+-------+ | Code | Name | Continent | Region | SurfaceArea | IndepYear | Population | LifeExpectancy | GNP | GNPOld | LocalName | GovernmentForm | HeadOfState | Capital | Code2 | +------+---------+---------------+--------------+-------------+-----------+------------+----------------+------------+------------+--------------+-------------------------+--------------+---------+-------+ | JAM | Jamaica | North America | Caribbean | 10990.00 | 1962 | 2583000 | 75.2 | 6871.00 | 6722.00 | Jamaica | Constitutional Monarchy | Elisabeth II | 1530 | JM | | JOR | Jordan | Asia | Middle East | 88946.00 | 1946 | 5083000 | 77.4 | 7526.00 | 7051.00 | Al-Urdunn | Constitutional Monarchy | Abdullah II | 1786 | JO | | JPN | Japan | Asia | Eastern Asia | 377829.00 | -660 | 126714000 | 80.7 | 3787042.00 | 4192638.00 | Nihon/Nippon | Constitutional Monarchy | Akihito | 1532 | JP | +------+---------+---------------+--------------+-------------+-----------+------------+----------------+------------+------------+--------------+-------------------------+--------------+---------+-------+ 3 rows in set (0.00 sec)
J で始まる国は、ジャマイカとヨルダンと日本だけだった。では、同じように国名が 'K' で始まり、かつアジア大陸にある国だけを取ってきてほしい場合はどうすればいいだろう。その場合は、 WHERE Continent = 'Asia'
と WHERE Name LIKE 'K%'
のふたつの条件を組み合わせなければならない。
テーブルの中から複数条件のすべてに一致するデータを取得する(SELECT カラム名 FROM テーブル名 WHERE 条件 AND 条件)
複数条件を指定したい場合、WHERE
のあとにふたつ以上の条件を AND
でつなげることで指定することができる。WHERE Continent = 'Asia'
と WHERE Name LIKE 'K%'
なら、WHERE Continent = 'Asia' AND Name LIKE 'K%'
(WHERE
はひとつで良い)になる。
mysql> SELECT * FROM country WHERE Name LIKE 'K%' AND continent = 'Asia'; +------+------------+-----------+---------------------------+-------------+-----------+------------+----------------+----------+----------+------------+-----------------------------------+----------------------------------+---------+-------+ | Code | Name | Continent | Region | SurfaceArea | IndepYear | Population | LifeExpectancy | GNP | GNPOld | LocalName | GovernmentForm | HeadOfState | Capital | Code2 | +------+------------+-----------+---------------------------+-------------+-----------+------------+----------------+----------+----------+------------+-----------------------------------+----------------------------------+---------+-------+ | KAZ | Kazakstan | Asia | Southern and Central Asia | 2724900.00 | 1991 | 16223000 | 63.2 | 24375.00 | 23383.00 | Qazaqstan | Republic | Nursultan Nazarbajev | 1864 | KZ | | KGZ | Kyrgyzstan | Asia | Southern and Central Asia | 199900.00 | 1991 | 4699000 | 63.4 | 1626.00 | 1767.00 | Kyrgyzstan | Republic | Askar Akajev | 2253 | KG | | KWT | Kuwait | Asia | Middle East | 17818.00 | 1961 | 1972000 | 76.1 | 27037.00 | 30373.00 | Al-Kuwayt | Constitutional Monarchy (Emirate) | Jabir al-Ahmad al-Jabir al-Sabah | 2429 | KW | +------+------------+-----------+---------------------------+-------------+-----------+------------+----------------+----------+----------+------------+-----------------------------------+----------------------------------+---------+-------+ 3 rows in set (0.00 sec)
カザフスタンとキルギスとクウェートが条件に合致した。では、国名の先頭が 'K' もしくは 'P' の国ではどうだろうか。
テーブルの中から複数条件のいずれかまたは両方に一致するデータを取得する(SELECT カラム名 FROM テーブル名 WHERE 条件 OR 条件)
いずれかまたは両方に合致させたい複数条件を指定する場合、WHERE
のあとにふたつ以上の条件を OR
でつなげることで指定することができる。WHERE Name LIKE 'P%'
と WHERE Name LIKE 'K%'
なら、WHERE Name LIKE 'P%' OR Name LIKE 'K%'
(WHERE
はひとつで良い)になる。
mysql> SELECT Name, Continent FROM country WHERE Name LIKE 'P%' OR Name LIKE 'K%'; +------------------+---------------+ | Name | Continent | +------------------+---------------+ | Kazakstan | Asia | | Kenya | Africa | | Kyrgyzstan | Asia | | Kiribati | Oceania | | Kuwait | Asia | | Pakistan | Asia | | Panama | North America | | Pitcairn | Oceania | | Peru | South America | | Philippines | Asia | | Palau | Oceania | | Papua New Guinea | Oceania | | Poland | Europe | | Puerto Rico | North America | | Portugal | Europe | | Paraguay | South America | | Palestine | Asia | +------------------+---------------+ 17 rows in set (0.00 sec)
無事取得することができた。さらにアジア大陸の国だけに絞る場合、 Continent = 'Asia'
を条件に追加する必要がある。大陸の指定は、Pで始まる国でもKで始まる国でも絞り込みたい条件なので、 OR
で追加することはできない。そのまま AND
でつなげた場合、以下のようになる。
mysql> SELECT Name, Continent FROM country WHERE Name LIKE 'P%' OR Name LIKE 'K%' AND Continent = 'Asia'; +------------------+---------------+ | Name | Continent | +------------------+---------------+ | Kazakstan | Asia | | Kyrgyzstan | Asia | | Kuwait | Asia | | Pakistan | Asia | | Panama | North America | | Pitcairn | Oceania | | Peru | South America | | Philippines | Asia | | Palau | Oceania | | Papua New Guinea | Oceania | | Poland | Europe | | Puerto Rico | North America | | Portugal | Europe | | Paraguay | South America | | Palestine | Asia | +------------------+---------------+ 15 rows in set (0.00 sec)
Kで始まる国についてはアジア大陸だけに絞り込まれているが、Pで始まる国については絞り込めていない。これは、 WHERE Name LIKE 'P%' OR Name LIKE 'K%' AND Continent = 'Asia'
という条件が、「国名がPで始まる」もしくは「国名がKで始まり、かつ大陸がアジア」という意味になってしまっているからだ。これを「国名がPで始まる」または「国名がKで始まる」、かつ「大陸がアジア」としたい場合、またはの条件のほうをカッコで囲み、WHERE ( Name LIKE 'P%' OR Name LIKE 'K%' ) AND Continent = 'Asia'
のようにする。
mysql> SELECT Name, Continent FROM country WHERE ( Name LIKE 'P%' OR Name LIKE 'K%' ) AND Continent = 'Asia'; +-------------+-----------+ | Name | Continent | +-------------+-----------+ | Kazakstan | Asia | | Kyrgyzstan | Asia | | Kuwait | Asia | | Pakistan | Asia | | Philippines | Asia | | Palestine | Asia | +-------------+-----------+ 6 rows in set (0.00 sec)
無事絞り込めた。ところで国名がアルファベット順になっていないので、これを並び替えたい。
テーブルの取得結果をカラムの内容で並び替える(SELECT カラム名 FROM テーブル名 ORDER BY カラム名 昇順または降順)
SELECT での取得結果を並び替えて表示したい場合、 ORDER BY カラム名
に続けて、昇順(ASC)または降順(DESC)を指定すれば良い(指定しなかった場合昇順になる)。
mysql> SELECT Name, Continent FROM country WHERE ( Name LIKE 'P%' OR Name LIKE 'K%' ) AND Continent = 'Asia' ORDER BY Name ASC; +-------------+-----------+ | Name | Continent | +-------------+-----------+ | Kazakstan | Asia | | Kuwait | Asia | | Kyrgyzstan | Asia | | Pakistan | Asia | | Palestine | Asia | | Philippines | Asia | +-------------+-----------+ 6 rows in set (0.00 sec)
アルファベットの昇順になった。これを応用して、たとえば世界の面積の大きな国のランキングを見ることもできる。
mysql> SELECT Name, SurfaceArea FROM country ORDER BY SurfaceArea DESC LIMIT 10; +--------------------+-------------+ | Name | SurfaceArea | +--------------------+-------------+ | Russian Federation | 17075400.00 | | Antarctica | 13120000.00 | | Canada | 9970610.00 | | China | 9572900.00 | | United States | 9363520.00 | | Brazil | 8547403.00 | | Australia | 7741220.00 | | India | 3287263.00 | | Argentina | 2780400.00 | | Kazakstan | 2724900.00 | +--------------------+-------------+ 10 rows in set (0.00 sec)
テーブルの取得条件に以上、以下を使う(SELECT カラム名 FROM テーブル名 WHERE カラム名 >= 数値 OR カラム名 <= 数値)
>=
,<=
,>
,<
を使うことで、以上、以下、より大きい、未満、を指定することができる。たとえば平均余命(LifeExpectancy)が80歳以上の国を取ってくる場合、 WHERE LifeExpectancy >= 80
のように指定する。
mysql> SELECT Name, LifeExpectancy FROM country WHERE LifeExpectancy >= 80; +------------+----------------+ | Name | LifeExpectancy | +------------+----------------+ | Andorra | 83.5 | | Japan | 80.7 | | Macao | 81.6 | | Singapore | 80.1 | | San Marino | 81.1 | +------------+----------------+ 5 rows in set (0.00 sec)
逆に平均余命が40歳以下の国は、以下のように取ってくることができる。
mysql> SELECT Name, LifeExpectancy FROM country WHERE LifeExpectancy <= 40; +------------+----------------+ | Name | LifeExpectancy | +------------+----------------+ | Angola | 38.3 | | Botswana | 39.3 | | Mozambique | 37.5 | | Malawi | 37.6 | | Rwanda | 39.3 | | Zambia | 37.2 | | Zimbabwe | 37.8 | +------------+----------------+ 7 rows in set (0.00 sec)
テーブルの全件数を取得する(SELECT COUNT(*) FROM テーブル名)
特定のテーブルで管理されているデータの全件数が取得したい場合、 SELECT * FROM テーブル名
で全件取得することで確認することもできるが、取得対象カラム名に COUNT(*)
を指定することで、もっとスマートに件数だけを取ってきてもらうこともできる。
mysql> SELECT COUNT(*) FROM country; +----------+ | COUNT(*) | +----------+ | 239 | +----------+ 1 row in set (0.00 sec)
COUNT(*)
は COUNT(1)
と表記しても良い。
mysql> SELECT COUNT(1) FROM country; +----------+ | COUNT(1) | +----------+ | 239 | +----------+ 1 row in set (0.03 sec)
では、大陸別の国の数を取ってきてみたい。大陸(Continent)でまとめることができれば、数えることができそうだ。
テーブルの内容を特定のカラムの内容でグループ分けする(SELECT * FROM テーブル名 GROUP BY カラム名)
GROUP BY カラム名
を指定することで、指定したカラムの内容でまとめた結果を取得することができる。これは主に COUNT()
などの複数のカラムの内容をまとめるコマンドと併用する。併用しなかった場合、以下のようにまとめられたうちの1件だけが表示される。
mysql> SELECT Name, Continent FROM country GROUP BY Continent; +----------------+---------------+ | Name | Continent | +----------------+---------------+ | Afghanistan | Asia | | Albania | Europe | | Aruba | North America | | Angola | Africa | | American Samoa | Oceania | | Antarctica | Antarctica | | Argentina | South America | +----------------+---------------+ 7 rows in set (0.00 sec)
ここで COUNT(*)
を併用すると、以下のようになる。
mysql> SELECT COUNT(1), Continent FROM country GROUP BY Continent; +----------+---------------+ | COUNT(1) | Continent | +----------+---------------+ | 51 | Asia | | 46 | Europe | | 37 | North America | | 58 | Africa | | 28 | Oceania | | 5 | Antarctica | | 14 | South America | +----------+---------------+ 7 rows in set (0.00 sec)
アフリカ大陸の国が一番多いことがわかった。COUNT()
と同じように、GROUP BY
と組み合わせて取得結果を操作するコマンドは他にもある。
指定されたカラムの最大値、最小値を取得する(SELECT MAX(カラム名), MIN(カラム名) FROM テーブル名 GROUP BY カラム名)
MAX()
とMIN()
を使うことで、最大値と最小値を取得することができる(MAX()
とMIN()
はもちろん個別に使うこともできる)。
mysql> SELECT MAX(SurfaceArea), MIN(SurfaceArea), Continent FROM country GROUP BY Continent; +------------------+------------------+---------------+ | MAX(SurfaceArea) | MIN(SurfaceArea) | Continent | +------------------+------------------+---------------+ | 9572900.00 | 18.00 | Asia | | 17075400.00 | 0.40 | Europe | | 9970610.00 | 53.00 | North America | | 2505813.00 | 78.00 | Africa | | 7741220.00 | 12.00 | Oceania | | 13120000.00 | 59.00 | Antarctica | | 8547403.00 | 12173.00 | South America | +------------------+------------------+---------------+ 7 rows in set (0.00 sec)
アジア最大の国は9572900.00平方km、最小の国は18.00平方kmであることがわかった。(それぞれ =
で指定して国名を調べてみても面白いかもしれない)
指定されたカラムに登録されている内容の合計値を取得する(SELECT SUM(カラム名) FROM テーブル名)
SUM(カラム名)
を使うことで、合計値が取得できる。
mysql> SELECT SUM(SurfaceArea), Continent FROM country GROUP BY Continent; +------------------+---------------+ | SUM(SurfaceArea) | Continent | +------------------+---------------+ | 31881005.00 | Asia | | 23049133.90 | Europe | | 24214470.00 | North America | | 30250377.00 | Africa | | 8564294.00 | Oceania | | 13132101.00 | Antarctica | | 17864926.00 | South America | +------------------+---------------+ 7 rows in set (0.01 sec)
各大陸の国の面積の合計値(=各大陸の面積?)が取得できた。
指定されたカラムに登録されている内容の文字数を取得する(SELECT LENGTH(カラム名) FROM テーブル名)
LENGTH(カラム名)
を指定することで、その内容の文字数を取得することができる。SUM()
と組み合わせて、以下のようなこともできる。
mysql> SELECT SUM(LENGTH(Name)), Continent FROM country GROUP BY Continent; +-------------------+---------------+ | SUM(LENGTH(Name)) | Continent | +-------------------+---------------+ | 396 | Asia | | 425 | Europe | | 446 | North America | | 547 | Africa | | 359 | Oceania | | 127 | Antarctica | | 113 | South America | +-------------------+---------------+ 7 rows in set (0.01 sec)
各大陸の国名の英語表記名の文字数合計が取得できた。(国名が20文字以上の国の一覧や、5文字以下の国一覧を取ってきても面白いかもしれない)
指定されたカラムに登録されている内容を重複を取り除いて表示する(SELECT DISTINCT カラム名 FROM テーブル名)
DISTINCT カラム名
を使うことで、重複を取り除いた結果を取得することができる。
mysql> SELECT DISTINCT Continent FROM country; +---------------+ | Continent | +---------------+ | North America | | Asia | | Africa | | Europe | | South America | | Oceania | | Antarctica | +---------------+ 7 rows in set (0.00 sec)
大陸名(Continent)を指定することで、その内容を重複なしで取ってこれた。
複数のカラムの内容や文字列を結合して結果に含める(SELECT CONCAT(文字列やカラム名, 文字列やカラム名, ...) FROM テーブル名)
CONCAT()
を使うことで、複数の文字の結合をすることができる。'Hello!'
' '
'World!'
の3つの文字列を組み合わせるには、以下のようにする。
mysql> SELECT CONCAT('Hello!', ' ', 'World!'); +---------------------------------+ | CONCAT('Hello!', ' ', 'World!') | +---------------------------------+ | Hello! World! | +---------------------------------+ 1 row in set (0.01 sec)
文字列の代わりにカラム名を指定することもできる。たとえば国名と大陸名をくっつけて表示したい場合、以下のようにする。
mysql> SELECT CONCAT(Name, ' (', Continent, ')') FROM country LIMIT 10; +--------------------------------------+ | CONCAT(Name, ' (', Continent, ')') | +--------------------------------------+ | Aruba (North America) | | Afghanistan (Asia) | | Angola (Africa) | | Anguilla (North America) | | Albania (Europe) | | Andorra (Europe) | | Netherlands Antilles (North America) | | United Arab Emirates (Asia) | | Argentina (South America) | | Armenia (Asia) | +--------------------------------------+ 10 rows in set (0.00 sec)
CONCAT(Name, ' (', Continent, ')')
の表示が少し見づらいので、これに別名をつけてみたい。
取得結果に別名をつける(SELECT 取得結果 AS 別名)
AS 別名
を追加することで、別名をつけることができる。
mysql> SELECT CONCAT(Name, ' (', Continent, ')') AS NameContinent FROM country LIMIT 10; +--------------------------------------+ | NameContinent | +--------------------------------------+ | Aruba (North America) | | Afghanistan (Asia) | | Angola (Africa) | | Anguilla (North America) | | Albania (Europe) | | Andorra (Europe) | | Netherlands Antilles (North America) | | United Arab Emirates (Asia) | | Argentina (South America) | | Armenia (Asia) | +--------------------------------------+ 10 rows in set (0.00 sec)
この別名は、並び替えのカラム名にも指定することができる。
mysql> SELECT CONCAT(Name, ' (', Continent, ')') AS NameContinent FROM country ORDER BY NameContinent LIMIT 10; +-------------------------------------+ | NameContinent | +-------------------------------------+ | Afghanistan (Asia) | | Albania (Europe) | | Algeria (Africa) | | American Samoa (Oceania) | | Andorra (Europe) | | Angola (Africa) | | Anguilla (North America) | | Antarctica (Antarctica) | | Antigua and Barbuda (North America) | | Argentina (South America) | +-------------------------------------+ 10 rows in set (0.01 sec)
ふたつのテーブルを組み合わせて結果を取得する
さて、ここまで一通りの取得操作を見てきた。これで、ひとつのテーブルからデータを取ってくることは、一通りできるようになったと思う。では、ここからはふたつのテーブルの内容を組み合わせて表示する方法を説明していく。すこし複雑になるので、わからなくなったら、無理せずまたここに戻ってきてほしい。
いままで country
テーブルを使って説明してきたが、 world
データベースの中には他にもテーブルがある。
mysql> SHOW TABLES; +-----------------+ | Tables_in_world | +-----------------+ | city | | country | | countrylanguage | +-----------------+ 3 rows in set (0.00 sec)
city
を見てみよう。
mysql> DESC city; +-------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------+------+-----+---------+----------------+ | ID | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | CountryCode | char(3) | NO | MUL | | | | District | char(20) | NO | | | | | Population | int(11) | NO | | 0 | | +-------------+----------+------+-----+---------+----------------+ 5 rows in set (0.03 sec)
ID番号、名前、国コード、県名、人口が登録されているようだ。では、試しに都市名(Name)が 'Tripoli'
(トリポリ)になっている都市を探してみよう。
mysql> select * from city where Name = 'Tripoli'; +------+---------+-------------+-----------+------------+ | ID | Name | CountryCode | District | Population | +------+---------+-------------+-----------+------------+ | 2439 | Tripoli | LBN | al-Shamal | 240000 | | 2441 | Tripoli | LBY | Tripoli | 1682000 | +------+---------+-------------+-----------+------------+ 2 rows in set (0.00 sec)
該当する都市が2件見つかった。それぞれ CountryCode
が LBN, LBY となっているが、これだけでは国名がはっきりしない*6。国コードを使って、以下のように個別に調べてやることもできる。
mysql> select * from country WHERE Code = 'LBN'; +------+---------+-----------+-------------+-------------+-----------+------------+----------------+----------+----------+-----------+----------------+---------------+---------+-------+ | Code | Name | Continent | Region | SurfaceArea | IndepYear | Population | LifeExpectancy | GNP | GNPOld | LocalName | GovernmentForm | HeadOfState | Capital | Code2 | +------+---------+-----------+-------------+-------------+-----------+------------+----------------+----------+----------+-----------+----------------+---------------+---------+-------+ | LBN | Lebanon | Asia | Middle East | 10400.00 | 1941 | 3282000 | 71.3 | 17121.00 | 15129.00 | Lubnan | Republic | Émile Lahoud | 2438 | LB | +------+---------+-----------+-------------+-------------+-----------+------------+----------------+----------+----------+-----------+----------------+---------------+---------+-------+ 1 row in set (0.00 sec)
ふたつのテーブルに該当する行を結合して取得する(INNER JOIN)
LBN はレバノンだとわかった。しかし、こうやっていちいち該当するデータを別のテーブルから検索してくるのは手間がかかりすぎる。そこで、city
と country
の内容を結合して表示したい。結合するには、 INNER JOIN
を使用する。city
テーブルに対して country
テーブルを結合するので、 SELECT * FROM city INNER JOIN country WHERE Name = 'Tripoli';
とする。これを実行すると以下のようになる。
mysql> SELECT * FROM city INNER JOIN country WHERE Name = 'Tripoli'; ERROR 1052 (23000): Column 'Name' in where clause is ambiguous
エラーメッセージの中の ambiguous
とは「曖昧な」という意味で、エラーメッセージ全体では「WHERE の中に書いてある 'Name' というカラム名は曖昧だ」と言われている。どういうことだろうか。それぞれのテーブルをよく見てみよう。
mysql> DESC city; +-------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------+------+-----+---------+----------------+ | ID | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | CountryCode | char(3) | NO | MUL | | | | District | char(20) | NO | | | | | Population | int(11) | NO | | 0 | | +-------------+----------+------+-----+---------+----------------+ 5 rows in set (0.01 sec) mysql> DESC country; +----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+ | Code | char(3) | NO | PRI | | | | Name | char(52) | NO | | | | | Continent | enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') | NO | | Asia | | | Region | char(26) | NO | | | | | SurfaceArea | float(10,2) | NO | | 0.00 | | | IndepYear | smallint(6) | YES | | NULL | | | Population | int(11) | NO | | 0 | | | LifeExpectancy | float(3,1) | YES | | NULL | | | GNP | float(10,2) | YES | | NULL | | | GNPOld | float(10,2) | YES | | NULL | | | LocalName | char(45) | NO | | | | | GovernmentForm | char(45) | NO | | | | | HeadOfState | char(60) | YES | | NULL | | | Capital | int(11) | YES | | NULL | | | Code2 | char(2) | NO | | | | +----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+ 15 rows in set (0.00 sec)
Name カラムに注目しよう。両方のテーブルに 'Name' カラムがあることがわかるはずだ。「曖昧だ」というのはつまり、「city テーブルの中の Name カラムなのか、country テーブルの中の Name カラムなのかが曖昧だ」という意味なのだ。どちらのテーブルの Name カラムなのか、はっきりと指定してやる必要がある。指定したいのは city
テーブルなので、city.Name
のように書くことができる。SELECT * FROM city INNER JOIN country WHERE city.Name = 'Tripoli';
これを実行すると、以下のようになる。
mysql> SELECT * FROM city INNER JOIN country WHERE city.Name = 'Tripoli'; +------+---------+-------------+-----------+------------+------+----------------------------------------------+---------------+---------------------------+-------------+-----------+------------+----------------+------------+------------+----------------------------------------------+----------------------------------------------+--------------------------------------+---------+-------+ | ID | Name | CountryCode | District | Population | Code | Name | Continent | Region | SurfaceArea | IndepYear | Population | LifeExpectancy | GNP | GNPOld | LocalName | GovernmentForm | HeadOfState | Capital | Code2 | +------+---------+-------------+-----------+------------+------+----------------------------------------------+---------------+---------------------------+-------------+-----------+------------+----------------+------------+------------+----------------------------------------------+----------------------------------------------+--------------------------------------+---------+-------+ | 2439 | Tripoli | LBN | al-Shamal | 240000 | ABW | Aruba | North America | Caribbean | 193.00 | NULL | 103000 | 78.4 | 828.00 | 793.00 | Aruba | Nonmetropolitan Territory of The Netherlands | Beatrix | 129 | AW | | 2439 | Tripoli | LBN | al-Shamal | 240000 | AFG | Afghanistan | Asia | Southern and Central Asia | 652090.00 | 1919 | 22720000 | 45.9 | 5976.00 | NULL | Afganistan/Afqanestan | Islamic Emirate | Mohammad Omar | 1 | AF | | 2439 | Tripoli | LBN | al-Shamal | 240000 | AGO | Angola | Africa | Central Africa | 1246700.00 | 1975 | 12878000 | 38.3 | 6648.00 | 7984.00 | Angola | Republic | José Eduardo dos Santos | 56 | AO | (中略) | 2441 | Tripoli | LBY | Tripoli | 1682000 | ZAF | South Africa | Africa | Southern Africa | 1221037.00 | 1910 | 40377000 | 51.1 | 116729.00 | 129092.00 | South Africa | Republic | Thabo Mbeki | 716 | ZA | | 2441 | Tripoli | LBY | Tripoli | 1682000 | ZMB | Zambia | Africa | Eastern Africa | 752618.00 | 1964 | 9169000 | 37.2 | 3377.00 | 3922.00 | Zambia | Republic | Frederick Chiluba | 3162 | ZM | | 2441 | Tripoli | LBY | Tripoli | 1682000 | ZWE | Zimbabwe | Africa | Eastern Africa | 390757.00 | 1980 | 11669000 | 37.8 | 5951.00 | 8670.00 | Zimbabwe | Republic | Robert G. Mugabe | 4068 | ZW | +------+---------+-------------+-----------+------------+------+----------------------------------------------+---------------+---------------------------+-------------+-----------+------------+----------------+------------+------------+----------------------------------------------+----------------------------------------------+--------------------------------------+---------+-------+ 478 rows in set (0.01 sec)
またも画面が文字で埋まってしまった。トリポリという都市は2つしかなかったはずなのに、なぜ478件も出てきてしまったのだろうか。それは、結合の対象にするカラム名を指定していないからだ。結合対象のカラムを指定していない場合、データベースの管理人は以下のように考えてしまう。
- city テーブルから、Name が Tripoli になっている行を取ってくる。2件だった。
- country テーブルから、全件取ってくる。239件だった。
- 結合対象カラムが指定されていないので、cityの結果1件ずつに、それぞれ239件のcountryの結果を組み合わせよう。2件 x 239件 = 478件の結果ができた。
これは望んだ結果ではないので、コマンドを修正しよう。city.CountryCode
と country.Code
を結合してほしいので、指定を追加する。 INNER JOIN テーブル名 ON 結合対象指定
と入力するので、 SELECT * FROM city INNER JOIN country ON city.CountryCode = country.Code WHERE city.Name = 'Tripoli'
となった。
mysql> SELECT * FROM city INNER JOIN country ON city.CountryCode = country.Code WHERE city.Name = 'Tripoli'; +------+---------+-------------+-----------+------------+------+------------------------+-----------+-----------------+-------------+-----------+------------+----------------+----------+----------+-----------+-------------------+--------------------+---------+-------+ | ID | Name | CountryCode | District | Population | Code | Name | Continent | Region | SurfaceArea | IndepYear | Population | LifeExpectancy | GNP | GNPOld | LocalName | GovernmentForm | HeadOfState | Capital | Code2 | +------+---------+-------------+-----------+------------+------+------------------------+-----------+-----------------+-------------+-----------+------------+----------------+----------+----------+-----------+-------------------+--------------------+---------+-------+ | 2439 | Tripoli | LBN | al-Shamal | 240000 | LBN | Lebanon | Asia | Middle East | 10400.00 | 1941 | 3282000 | 71.3 | 17121.00 | 15129.00 | Lubnan | Republic | Émile Lahoud | 2438 | LB | | 2441 | Tripoli | LBY | Tripoli | 1682000 | LBY | Libyan Arab Jamahiriya | Africa | Northern Africa | 1759540.00 | 1951 | 5605000 | 75.5 | 44806.00 | 40562.00 | Libiya | Socialistic State | Muammar al-Qadhafi | 2441 | LY | +------+---------+-------------+-----------+------------+------+------------------------+-----------+-----------------+-------------+-----------+------------+----------------+----------+----------+-----------+-------------------+--------------------+---------+-------+ 2 rows in set (0.00 sec)
さきほどよりは平和な結果になった。しかし横長で見えづらいので、見たい情報だけに絞って表示しよう。 *
の部分を見たいカラムの指定に変更する。だからといってただ単にカラム名を記述してしまうと、以下のようになってしまう。
mysql> SELECT ID, Name, CountryCode, District, Population, Name FROM city INNER JOIN country ON city.CountryCode = country.Code WHERE city.Name = 'Tripoli'; ERROR 1052 (23000): Column 'Name' in field list is ambiguous
また「曖昧だ」とエラーメッセージが出てくるので、同じようにテーブル名込みで指定しよう。
mysql> SELECT city.ID, city.Name, city.CountryCode, city.District, city.Population, country.Name FROM city INNER JOIN country ON city.CountryCode = country.Code WHERE city.Name = 'Tripoli'; +------+---------+-------------+-----------+------------+------------------------+ | ID | Name | CountryCode | District | Population | Name | +------+---------+-------------+-----------+------------+------------------------+ | 2439 | Tripoli | LBN | al-Shamal | 240000 | Lebanon | | 2441 | Tripoli | LBY | Tripoli | 1682000 | Libyan Arab Jamahiriya | +------+---------+-------------+-----------+------------+------------------------+ 2 rows in set (0.00 sec)
しかし、結果の Name
にテーブル名が含まれていないので、別名をつけてやることにする。
mysql> SELECT city.ID, city.Name AS CityName, city.CountryCode, city.District, city.Population, country.Name AS CountryName FROM city INNER JOIN country ON city.CountryCode = country.Code WHERE city.Name = 'Tripoli'; +------+----------+-------------+-----------+------------+------------------------+ | ID | CityName | CountryCode | District | Population | CountryName | +------+----------+-------------+-----------+------------+------------------------+ | 2439 | Tripoli | LBN | al-Shamal | 240000 | Lebanon | | 2441 | Tripoli | LBY | Tripoli | 1682000 | Libyan Arab Jamahiriya | +------+----------+-------------+-----------+------------+------------------------+ 2 rows in set (0.01 sec)
また、別名と組み合わせることはできないが、 テーブル名.*
を使ってカラム指定を省略することができる。*
を使っていないテーブルのカラムには、別名をつけても問題ない。
mysql> SELECT city.*, country.Name AS CountryName FROM city INNER JOIN country ON city.CountryCode = country.Code WHERE city.Name = 'Tripoli'; +------+---------+-------------+-----------+------------+------------------------+ | ID | Name | CountryCode | District | Population | CountryName | +------+---------+-------------+-----------+------------+------------------------+ | 2439 | Tripoli | LBN | al-Shamal | 240000 | Lebanon | | 2441 | Tripoli | LBY | Tripoli | 1682000 | Libyan Arab Jamahiriya | +------+---------+-------------+-----------+------------+------------------------+ 2 rows in set (0.00 sec)
ふたつのテーブルに該当する行と、片方にだけある行を結合して取得する(LEFT OUTER JOIN, RIGHT OUTER JOIN)
ところで、 countryLanguage
テーブルを見てみよう。
mysql> DESC countryLanguage; +-------------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+---------------+------+-----+---------+-------+ | CountryCode | char(3) | NO | PRI | | | | Language | char(30) | NO | PRI | | | | IsOfficial | enum('T','F') | NO | | F | | | Percentage | float(4,1) | NO | | 0.0 | | +-------------+---------------+------+-----+---------+-------+ 4 rows in set (0.01 sec)
CountryCode
が 'JPN'
になっているレコードを見てみると、以下のようになっている。
mysql> select * from countryLanguage WHERE CountryCode = 'JPN'; +-------------+----------------------+------------+------------+ | CountryCode | Language | IsOfficial | Percentage | +-------------+----------------------+------------+------------+ | JPN | Ainu | F | 0.0 | | JPN | Chinese | F | 0.2 | | JPN | English | F | 0.1 | | JPN | Japanese | T | 99.1 | | JPN | Korean | F | 0.5 | | JPN | Philippene Languages | F | 0.1 | +-------------+----------------------+------------+------------+ 6 rows in set (0.01 sec)
日本で話されている言語と、話者の割合が管理されていることがわかる。 Language
を指定すれば、その言語が話されている国と割合がわかる。
mysql> select * from countryLanguage WHERE Language = 'English'; +-------------+----------+------------+------------+ | CountryCode | Language | IsOfficial | Percentage | +-------------+----------+------------+------------+ | ABW | English | F | 9.5 | | AIA | English | T | 0.0 | | ANT | English | F | 7.8 | (中略) | WSM | English | T | 0.6 | | ZAF | English | T | 8.5 | | ZWE | English | T | 2.2 | +-------------+----------+------------+------------+ 60 rows in set (0.01 sec)
英語が60カ国で話されていることがわかった。では、国の一覧と、その国の英語話者の割合を一覧にしてみよう。INNER JOIN で、 country
テーブルの一覧と countryLanguage
テーブルを Language = 'English'
で絞り込んだ結果一覧とを結合する。
mysql> SELECT country.Code, country.Name AS CountryName, countryLanguage.Language, countryLanguage.IsOfficial, countryLanguage.Percentage FROM country INNER JOIN countryLanguage ON country.Code = countryLanguage.CountryCode WHERE Language = 'English'; +------+--------------------------------------+----------+------------+------------+ | Code | CountryName | Language | IsOfficial | Percentage | +------+--------------------------------------+----------+------------+------------+ | ABW | Aruba | English | F | 9.5 | | AIA | Anguilla | English | T | 0.0 | | ANT | Netherlands Antilles | English | F | 7.8 | (中略) | WSM | Samoa | English | T | 0.6 | | ZAF | South Africa | English | T | 8.5 | | ZWE | Zimbabwe | English | T | 2.2 | +------+--------------------------------------+----------+------------+------------+ 60 rows in set (0.01 sec)
たしかに結果一覧が出たが、一覧には、英語を話していない国も一緒に含めたい。INNER JOIN では、結合するふたつのテーブル両方にある行しか結果一覧に含めない。そこで、この場合には OUTER JOIN を使用する。
mysql> SELECT country.Code, country.Name AS CountryName, countryLanguage.Language, countryLanguage.IsOfficial, countryLanguage.Percentage FROM country LEFT JOIN countryLanguage ON country.Code = countryLanguage.CountryCode AND countryLanguage.Language = 'English'; +------+----------------------------------------------+----------+------------+------------+ | Code | CountryName | Language | IsOfficial | Percentage | +------+----------------------------------------------+----------+------------+------------+ | ABW | Aruba | English | F | 9.5 | | AFG | Afghanistan | NULL | NULL | NULL | | AGO | Angola | NULL | NULL | NULL | (中略) | ZAF | South Africa | English | T | 8.5 | | ZMB | Zambia | NULL | NULL | NULL | | ZWE | Zimbabwe | English | T | 2.2 | +------+----------------------------------------------+----------+------------+------------+ 239 rows in set (0.00 sec)
また、この場合には countryLanguage.Language = 'English'
の条件を WHERE
に含めず、LEFT JOIN 手^ブル名 ON
の後に入力する。 WHERE
に含めた場合は、以下のようになる。
mysql> SELECT country.Code, country.Name AS CountryName, countryLanguage.Language, countryLanguage.IsOfficial, countryLanguage.Percentage FROM country LEFT JOIN countryLanguage ON country.Code = countryLanguage.CountryCode WHERE countryLanguage.Language = 'English'; +------+--------------------------------------+----------+------------+------------+ | Code | CountryName | Language | IsOfficial | Percentage | +------+--------------------------------------+----------+------------+------------+ | ABW | Aruba | English | F | 9.5 | | AIA | Anguilla | English | T | 0.0 | | ANT | Netherlands Antilles | English | F | 7.8 | (中略) | WSM | Samoa | English | T | 0.6 | | ZAF | South Africa | English | T | 8.5 | | ZWE | Zimbabwe | English | T | 2.2 | +------+--------------------------------------+----------+------------+------------+ 60 rows in set (0.00 sec)
結果が60件しか出てこず、 INNER JOIN
と同じになっている。これは、上のSQLを管理人が以下のように理解するからである*7。
- country テーブルから全件を取得する。結果は239件。
- countryLanguage テーブルから全件を取得する。結果は984件。
- 1と2の結果一覧を
country.Code = countryLanguage.CountryCode
の条件で結合する。 - 3の結果のうち、
countryLanguage.Language = 'English'
に該当する行だけに絞り込む。結果は60件。
これを ON に書くことで、以下のように解釈してもらえます。
- country テーブルから全件を取得する。結果は239件。
- countryLanguage テーブルのうち
countryLanguage.Language = 'English'
に該当する行だけに絞り込む。結果は60件。 - 1に2を
country.Code = countryLanguage.CountryCode
の条件で結合する。1のデータのうち2に該当する行が無いものも、結合結果に含める。結果は239件。
A LEFT JOIN B
の場合には A にしかないデータも結果に含まれ、 A RIGHT JOIN B
の場合には B にしかないデータも結果に含まれる。LEFT と RIGHT とでは、このテーブルの結合の方向が異なる。
結合の説明はここまで。
テーブルにデータを追加する(INSERT INTO テーブル名 ( カラム名 ) VALUES ( データ ))
世界に新しい国ができたとか、country
テーブルに不足しているデータがあった場合、データを追加する必要がでてくる。Excel では空白の行にデータを追加するが、MySQL ではコマンドでデータを追加する。追加先のテーブルを確認しよう。
mysql> DESC country; +----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+ | Code | char(3) | NO | PRI | | | | Name | char(52) | NO | | | | | Continent | enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') | NO | | Asia | | | Region | char(26) | NO | | | | | SurfaceArea | float(10,2) | NO | | 0.00 | | | IndepYear | smallint(6) | YES | | NULL | | | Population | int(11) | NO | | 0 | | | LifeExpectancy | float(3,1) | YES | | NULL | | | GNP | float(10,2) | YES | | NULL | | | GNPOld | float(10,2) | YES | | NULL | | | LocalName | char(45) | NO | | | | | GovernmentForm | char(45) | NO | | | | | HeadOfState | char(60) | YES | | NULL | | | Capital | int(11) | YES | | NULL | | | Code2 | char(2) | NO | | | | +----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+ 15 rows in set (0.00 sec)
追加するデータを用意して、INSERT コマンドを入力する。ここでは、オーランド諸島自治領が突然独立したものとして、データを追加する*8。
mysql> INSERT INTO country ( Code, Name, Continent, Region, SurfaceArea, IndepYear, Population, LifeExpectancy, GNP, GNPOld, LocalName, GovernmentForm, HeadOfState, Capital, Code2 ) VALUES ( 'ALA', 'Aland Islands', 'Europe', 'Nordic Countries', 13517.00, 1920, 28700, 82.5, 0, 0, 'Landskapet Åland', 'Parliamentary System', 'Sauli Väinämö Niinistö', null, 'AX' ); Query OK, 1 row affected (0.02 sec)
追加した結果を SELECT して確認する。
mysql> SELECT * FROM country WHERE Code = 'ALA'\G *************************** 1. row *************************** Code: ALA Name: Aland Islands Continent: Europe Region: Nordic Countries SurfaceArea: 13517.00 IndepYear: 1920 Population: 28700 LifeExpectancy: 82.5 GNP: 0.00 GNPOld: 0.00 LocalName: Landskapet Åland GovernmentForm: Parliamentary System HeadOfState: Sauli Väinämö Niinistö Capital: NULL Code2: AX 1 row in set (0.00 sec)
このままでは首都のマリエハムンが登録されていないので、Capital のデータを更新して、首都を設定しよう。DESC country;
の結果を見ればわかるように、 Capital
カラムは int(11)
というカラムタイプになっている。これは「11桁の数字」という意味で、スウェーデンの場合、以下のようになっている。
mysql> SELECT Code, Name, Capital FROM country WHERE Name = 'Sweden'; +------+--------+---------+ | Code | Name | Capital | +------+--------+---------+ | SWE | Sweden | 3048 | +------+--------+---------+ 1 row in set (0.00 sec)
この 3048
は、以下のように city
テーブルの ID
カラムの番号を意味している。
mysql> select * from city where ID=3048; +------+-----------+-------------+----------+------------+ | ID | Name | CountryCode | District | Population | +------+-----------+-------------+----------+------------+ | 3048 | Stockholm | SWE | Lisboa | 750348 | +------+-----------+-------------+----------+------------+ 1 row in set (0.00 sec)
オーランド諸島の首都マリエハムンを city テーブルで検索すると、以下のようになっている。
mysql> select * from city where Name='Mariehamn'; Empty set (0.01 sec)
無い。city
テーブルにも追加する必要がある。
mysql> desc city; +-------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------+------+-----+---------+----------------+ | ID | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | CountryCode | char(3) | NO | MUL | | | | District | char(20) | NO | | | | | Population | int(11) | NO | | 0 | | +-------------+----------+------+-----+---------+----------------+ 5 rows in set (0.00 sec)
確認すると、 city.ID
には auto_increment
という記載がある。これは「自動的に最大値+1を設定する」という意味で、新規にデータを追加した場合、何も指定しなければ最大値+1を設定してくれるようになっている。INSERT では基本的に ID
は指定せず、以下のようにする。
mysql> INSERT INTO city ( Name, CountryCode, District, Population ) VALUES ( 'Mariehamn', 'ALA', 'Aland', 11186 ); Query OK, 1 row affected (0.03 sec)
追加結果を確認する。
mysql> select * from city where Name='Mariehamn'; +------+-----------+-------------+----------+------------+ | ID | Name | CountryCode | District | Population | +------+-----------+-------------+----------+------------+ | 4080 | Mariehamn | ALA | Aland | 11186 | +------+-----------+-------------+----------+------------+ 1 row in set (0.00 sec)
ID
は 4080
が割り当てられている。 これで、country
テーブルの Capital
を更新する準備ができた。
テーブルのデータを更新する(UPDATE テーブル名 SET カラム名 = 変更内容 WHERE 条件)
INSERT で追加したオーランド諸島の首都IDを、新規に追加した city.ID
である 4080
で更新する。更新前、データは以下のように NULL
(空データ)になっている。
mysql> SELECT * FROM country WHERE Code = 'ALA'\G *************************** 1. row *************************** Code: ALA Name: Aland Islands Continent: Europe Region: Nordic Countries SurfaceArea: 13517.00 IndepYear: 1920 Population: 28700 LifeExpectancy: 82.5 GNP: 0.00 GNPOld: 0.00 LocalName: Landskapet Åland GovernmentForm: Parliamentary System HeadOfState: Sauli Väinämö Niinistö Capital: NULL Code2: AX 1 row in set (0.00 sec)
これを更新する。
mysql> UPDATE country SET Capital = 4080 WHERE Code = 'ALA'; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0
更新結果を確認する。
mysql> SELECT Code, Name, Capital FROM country WHERE Code = 'ALA'; +------+---------------+---------+ | Code | Name | Capital | +------+---------------+---------+ | ALA | Aland Islands | 4080 | +------+---------------+---------+ 1 row in set (0.00 sec)
UPDATE 時に WHERE
で条件を指定しなかった場合、 country
テーブルの全データが更新されてしまうので、意図していなければ気をつけてコマンドを入力しよう。実行した場合、以下のようになる。
mysql> UPDATE country SET Capital = 4080; Query OK, 240 row affected (0.01 sec) Rows matched: 240 Changed: 240 Warnings: 0
影響を受けた行が意図せず240行になっている。
データを削除する(DELETE FROM テーブル名 WHERE 条件)
先程追加したオーランド諸島のデータを削除してみよう。実施する前に、対象のデータを確認する。
mysql> SELECT * FROM country WHERE Code = 'ALA'\G *************************** 1. row *************************** Code: ALA Name: Aland Islands Continent: Europe Region: Nordic Countries SurfaceArea: 13517.00 IndepYear: 1920 Population: 28700 LifeExpectancy: 82.5 GNP: 0.00 GNPOld: 0.00 LocalName: Landskapet Åland GovernmentForm: Parliamentary System HeadOfState: Sauli Väinämö Niinistö Capital: 4080 Code2: AX 1 row in set (0.00 sec)
削除を実施する。しかし、以下のようにエラーになった。
mysql> DELETE FROM country WHERE Code = 'ALA'; ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`world`.`city`, CONSTRAINT `city_ibfk_1` FOREIGN KEY (`CountryCode`) REFERENCES `country` (`Code`))
これは、「country
テーブルの削除しようとしているデータに紐付いている他のテーブルのデータがあるので、削除できない」というエラーだ。その他のテーブルは city
で、カラム名は CountryCode
とのことだそうだ。つまり、 city
テーブルにある CountryCode = 'ALA'
のデータがあるので、country
テーブルの Code = 'ALA'
のデータも削除できないのだ。先に city
テーブルのデータを削除する必要がある。削除する前に確認しよう。
mysql> SELECT * FROM city WHERE CountryCode = 'ALA'; +------+-----------+-------------+----------+------------+ | ID | Name | CountryCode | District | Population | +------+-----------+-------------+----------+------------+ | 4080 | Mariehamn | ALA | Aland | 11186 | +------+-----------+-------------+----------+------------+ 1 row in set (0.00 sec)
確認してから、削除する。
mysql> DELETE FROM city WHERE CountryCode = 'ALA'; Query OK, 1 row affected (0.02 sec)
削除してから、また確認しよう。
mysql> SELECT * FROM city WHERE CountryCode = 'ALA'; Empty set (0.00 sec)
削除に成功したので、country からもデータを削除する。
mysql> DELETE FROM country WHERE Code = 'ALA'; Query OK, 1 row affected (0.02 sec)
削除してから、必ず確認する。
mysql> SELECT * FROM country WHERE Code = 'ALA'\G Empty set (0.00 sec)
今度は削除に成功した。
ここまでで、基本的な確認とデータ操作の説明を終わる。ここからは、データベースやテーブルの定義、変更などを簡単に説明する。
データベースの定義(CREATE DATABASE データベース名)
性質の異なる情報を同じ場所に保存しておくと、整理や取り出す時に混乱のもとになりがちだ。あれもこれも入れられる箱は入れる時には何も考えなくて良いので便利だが、いざ中身を見るときには中は大変なことになっているだろう。それを防ぐため、必要に応じてデータベースを分ける。
mysql> CREATE DATABASE `world2`; Query OK, 1 row affected (0.03 sec)
データベース定義文の確認(SHOW CREATE DATABASE データベース名)
一度作成したデータベースは、その作成時に使われたコマンドを再確認することができる。今作成した world2
データベースの定義文を見てみよう。
mysql> SHOW CREATE DATABASE world2; +----------+-----------------------------------------------------------------+ | Database | Create Database | +----------+-----------------------------------------------------------------+ | world2 | CREATE DATABASE `world2` /*!40100 DEFAULT CHARACTER SET utf8 */ | +----------+-----------------------------------------------------------------+ 1 row in set (0.00 sec)
/*!40100 DEFAULT CHARACTER SET utf8 */
の部分はデータベースで使用するデフォルトの文字コードの設定だが、文字コードについて説明し始めると長くなるのでここでは割愛する。
データベースの削除(DROP DATABASE データベース名)
定義済みのデータベースを削除することもできる。
mysql> DROP DATABASE world2; Query OK, 0 rows affected (0.09 sec)
あっけなく消えてしまう。バックアップを保存していない場合などは気軽に復元できないので気をつけること。
テーブルの定義(CREATE TABLE テーブル名...)
データベース同様に、テーブルも定義することができる。
mysql> CREATE TABLE test ( id serial, name text, created datetime default now() ); Query OK, 0 rows affected (0.05 sec) mysql> DESC test; +---------+---------------------+------+-----+-------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------+---------------------+------+-----+-------------------+----------------+ | id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | | name | text | YES | | NULL | | | created | datetime | YES | | CURRENT_TIMESTAMP | | +---------+---------------------+------+-----+-------------------+----------------+ 3 rows in set (0.00 sec)
ここでは詳細は説明しない。カラムの種別などこまごまとした設定ができる。
テーブルの定義文を確認する(SHOW CREATE TABLE テーブル名)
こちらもデータベース同様に、一度定義されたテーブルは、その作成時に使われたコマンドを再確認することができる。
mysql> SHOW CREATE TABLE test; +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | test | CREATE TABLE `test` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `name` text, `created` datetime DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
テーブルの削除(DROP TABLE テーブル名)
定義済みのテーブルを削除することもできる。
mysql> DROP TABLE test; Query OK, 0 rows affected (0.01 sec)
こちらもあっけなく消えてしまう。バックアップを保存していない場合などはやはり気軽に復元できないので気をつけること。
テーブルにカラムを追加する(ALTER TABLE テーブル名 ADD COLUMN カラム名 カラム設定)
カラムを追加して、定義済みのテーブルの内容を変更することができる。
mysql> ALTER TABLE test ADD COLUMN modified datetime default null ON UPDATE CURRENT_TIMESTAMP AFTER created; Query OK, 0 rows affected (1.21 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> desc test; +----------+---------------------+------+-----+-------------------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +----------+---------------------+------+-----+-------------------+-----------------------------+ | id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | | name | text | YES | | NULL | | | created | datetime | YES | | CURRENT_TIMESTAMP | | | modified | datetime | YES | | NULL | on update CURRENT_TIMESTAMP | +----------+---------------------+------+-----+-------------------+-----------------------------+ 4 rows in set (0.00 sec)
テーブルからカラムを削除する(ALTER TABLE テーブル名 DROP COLUMN カラム名)
定義済みのテーブルからカラムを削除することができる。
mysql> ALTER TABLE test DROP COLUMN modified; Query OK, 0 rows affected (0.07 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> desc test; +---------+---------------------+------+-----+-------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------+---------------------+------+-----+-------------------+----------------+ | id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | | name | text | YES | | NULL | | | created | datetime | YES | | CURRENT_TIMESTAMP | | +---------+---------------------+------+-----+-------------------+----------------+ 3 rows in set (0.00 sec)
コマンドを入力していて起こりがちなトラブル
最後に簡単に、よく起こりがちなトラブルについて触れておく。
コーテーションのとじ忘れ
以下のような表示になり、コマンドが終えられなくなってしまうことがある。
mysql> SELECT * FROM country WHERE Name ='Japan; '>
エンターキーを押し続けても、以下のように下に流れていくだけだ。
mysql> SELECT * FROM country WHERE Name ='Japan; '> '> '>
これは 'Japan
のように '
が不足しているから起きている現象で、次の '
を待っているので、コマンドが終わらなくなってしまっている。';
を入力してエンターキーを押すと、以下のように待ち状態を抜けられるので、改めて入力しよう。
mysql> SELECT * FROM country WHERE Name ='Japan; '> '> '> '; Empty set (0.01 sec)
他にあるあるなトラブルを思い出したら追加していく。
終わりに
なんだか随分長くなってしまった。書いてみて思ったが、やはりテーブルの結合が初学者のつまづきがちなポイントだと思う。とはいえ何度か使って慣れていけば、何も問題はないと思う。また、ここで説明した内容はデータベースサーバの持つ機能のうちのほんの一部でしかないし、説明を簡単にするために敢えて触れていないことや簡略化したことも多くある。データベースサーバには、大抵のやりたいことは叶えてくれるだけの機能が用意されているし、そのために内部はもっと複雑になっている。ぜひ、実際の動作やマニュアルをあたってみてほしい。
などと偉そうに書いてみたものの、調べてみると自分自身知らないことがたくさんあったので、それらについてここで説明しないまでも、とても勉強になったのでした。知識を自分なりにまとめるってすごく大切。
イタリア語版ミュータント・アンド・マスターマインドの舞台裏 〜エマヌエーレ・グラナテッロ、ミルコ・ペリチオーニ・インタビュー〜
執筆者:ルイージ "テンカー" カラファ (Luigi "Tencar" Carafa)
2018年2月1日 本家イタリア語版公開
2018年2月5日 非公式日本語版公開
まったくの偶然の出来事から記事が生まれることがあります。D&D(ダンジョンズ&ドラゴンズ)の優れたマスターであるエンリコ・カンティーレ(Enrico Cantile)とのチャットの中で、スーパーヒーローたちが活躍する宇宙を舞台にしたRPG、ミュータント・アンド・マスターマインド(Mutants & Masterminds)に出会ったこともまたそういった偶然の出来事です。
私はそれからイタリア語版RPGを制作担当したチームを探しはじめ、カイゾク・プレス社(Kaizoku Press)のエマヌエーレ・グラナテッロ(Emanuele Granatello)とミルコ・ペリチオーニ(Mirko Pellicioni)へのインタビューに成功しました。
ルイージ(筆者): ミュータント・アンド・マスターマインドをイタリアに持ち込むというアイデアは、いつどこで思い浮かんだのですか?
エマヌエーレ: 僕とミルコ・ペリチオーニとは何年も前からの知り合いで、僕たち(と、レリオ・ムーラス(Lelio Mulas)のことも忘れちゃいけないね)は、これまでに様々なプロジェクトに携わってきました(Fading Suns、Warcraft、ほかに実現はしませんでしたが Casal Pusterlengo 市郵便局の強盗)。僕は何年も前から、ウォーハンマーRPG第2版のテスト協力を通じてその編集者*1のことを知っていました。
僕たちは何か新しいものをもたらし、イタリアのRPG業界で勝鬨をあげたいと思っていました。それに僕たちはDCコミックスの『Legione』*2以来(ああ、Legione!懐かしい!)、本当に "インパクトのある" ものは見たことがなかった。そしてミュータント・アンド・マスターマインドは、これまた偶然にも、DCコミックスのゲームです(アメリカでは『DC アドベンチャーズ』という名前で出版されています)。
贔屓していると思われるかもしれませんが、それでも本当に、ミュータント・アンド・マスターマインドはスーパーヒーローのPRGだと思います。システムはすぐ覚えてすぐ遊べるようになっていて、信じられないぐらい柔軟です。おおむねD&Dと共通していますが、異なる点が2つあります。例えばより早いダメージの回復(バットマンシリーズの世界観でプレイしたい場合におあつらえ向き)、ポイントシステム(ゲームの柔軟性を、最近の他のゲームのレベルまで高めています)、複合システムはヒーローポイントのメカニズムにリンクしています(こういったジャンルの典型的なヒーローの行動とダークヒーローのジレンマとをすっきり解決し、いわゆる "ショッピングカート" のようにしてしまうことはありません)。
ヒーローパワーのシステム(本の中でも最も重要なルールです)についても、いわゆる "呪文のリスト" のようになることを避けるため、非常に簡潔にまとめられています。それにくわえて、キャラクターやアーキタイプのラピッドジェネレータ(高速生成システム)が用意されているので、プレイヤーは基本ルールブック(オールカラーで豊富なイラストつき)の中の、何十種類ものキャラクターやパワーをすぐに使用することができるようになっています。それから、主な設定を紹介するための二つのストーリー!ほかになにか必要ですか?もし足りないものが見つかったとしたら、僕は追加のエキスパンションを使います。ウェブサイトに用意されている基本ルールを直接ダウンロードしてみてください!
また、ミュータント・アンド・マスターマインドのマスタースクリーンや、PGやヴィランをより迅速に作成するために用意された、能力に関する分厚い(700ページ以上!)ルールブック、『パワープロフィール』(ゲームマスター向け、冒険やアドバイス、アイデア、いくつものサプライズが掲載されています。たとえば、魔法の章をご覧ください)も作りました。
ルイージ: 全体の翻訳をするのはどれぐらい難しいことですか?あなたがたにこの作品を委ねたのは誰ですか?
ミルコ: エマヌエーレとレリオの担当した翻訳作業には、かなり時間がかかりました。翻訳作業は、自分の言葉で文章をまとめるというだけでなく、通して読み、再読し、印刷してからさらに読み直し、第三者に読んでもらうことまでが含まれます(僕たちが変えなきゃと思っている作業もあります...時間がかかりすぎるからね!)。これが翻訳者の仕事です(模倣もありますが、これこそが本当の翻訳なのです)。グリーン・ローニンのスティーブ・ケンソン(Steve Kenson)とジョン・リーセウッサー(Jon Leitheusser)にも、ルールへの疑問や誤植の解消に関して、多大な助力をいただきました。グラフィックやレイアウトも尋常ではありませんでした。ミルコ・ペリチオーニ氏は最終段階での変更という、印刷上の大問題に直面しなければならなかった。それは銀河に打ち上げられた宇宙の侮辱であり、宇宙人の科学者たちは、将来ビッグバンの背景放射と一緒にこれについて研究することでしょう。
ルイージ: ルールブックのフォーマットはどのようにして決めましたか?
ミルコ: 単なるA4サイズではなく、本家同様にアメリカの用紙形式にすることを話し合って決めました。カバーについては、顧客に安く提供することを考え、最終的なコスト増につながるハードカバーでの装丁ではなくペーパーバックを採用しました。
エマヌエーレ: 当初僕は編み物のカバーを考えていましたが、ミルコは僕に、あまり独創的でないものを使うよう納得させました。僕たちは古風なソフトカバー装丁を、レギュラー版、そしてとても稀少なルッカ*3版(現在では手に入らず、タイプミスが目立ちます。Gronchi Rosa*4のような感じです)のふたつで採用しました(純粋なスーパーヒーロースタイルで)。ウールカバー付きの版なら冬のゲームプレイにも役立つし、きっと綺麗だったのに、残念です。(暖かさで世界は救われます。でも…Mr.Freeze にとってはダメでしょうけどね!)
ルイージ: あなたがたもRPGのプレイヤーですか?
ミルコ: 僕は1987年以来RPGを精力的に遊んできました。そもそもがRPGの大ファンで、それなしに今まで生きるのがまず無理でした。
エマヌエーレ: 間違いないですね。僕は1993年に(僕は同僚ほどのオタクではありません)、D&Dの赤箱*5からでした(正直に言うと、僕より先にRPGで遊んでた人たちは、ヒーロークエストをやっていました)。僕の一番のお気に入りは、いまだにウォーハンマーRPG(初版と第二版)です。でも、他にもすごく雑食に遊んできました。
僕はスター・ウォーズRPGも好きだし、クトゥルフの呼び声、Rifts(ああ、Rifts…サイバー女とロータリー、喜びと悲しみ)、ミュータント・クロニクルズ、Fading Suns、パラノイア…などなど。もちろん、様々な派生版やたくさんのD20で、AD&D(アドバンスト・ダンジョンズ&ドラゴンズ)も遊んできました。ミュータント・アンド・マスターマインド(とTrue20、その後継)は、システムの到達点だと僕は思います。僕にはスティーブ・ケンソン(Steve Kenson)*6がどうやってそれに成功したのかはわかりませんが、70年代にもたらされた残滓*7は、柔軟かつシネマチックな珠玉作を産み出しました(ヒットポイントとレベルなしで!)。
ミルコ: すべては、1987年に僕が最初にローンウルフのゲームブック、それからThe Dark Eye*8と出会い、RPGがいったいどういうものなのかまったく知らないままに購入したときから始まりました。幸いなことに、僕の住んでいたボローニャには僕のような愛好家の集まるグループ(“Circolo degli Scacchi”や“Ludoteca giocano i Grandi di Corticella”)がたくさんありました。もちろん、僕にとっての二番目のRPGはD&Dで、それからルーンクエスト、クトゥルフの呼び声、そのほかにもたくさんあります。僕は古くからの愛好家のひとりですが、過去15年間の新しい革新的なゲームのことも大好きです。
エマヌエーレ: 子供の頃から、女の子に人気がなく、何事にもうんざりしていて、その名に相応しいコンピューターやコンソールも持ち合わせていない、基本的にオタクになろうとしていた僕(彼らにまだのど仏が無かったころ、永遠の天使たち!)には2つの選択肢しかありませんでした。シリアルキラーになるか、はたまたRPGか。僕はその両方の活動に専念していて、はっきりとどちらかを選んだわけではありませんでした。僕はカゼルタにある僕の大きな家で、長いRPGセッションを開催しましたが、それが終わる頃には、プレイヤーもキャラクターも消えてしまいました(必ずしもこの順序ではありません)。事態が悪化しはじめた時、僕は今住んでいる日本へと移りました。RPGを遊ぶことは少なくなりましたが、翻訳することは増えました。
ルイージ: 紙のマニュアルの出版を補助する目的で、タブレットやその他のサポートが可能なPDF形式やその他形式で配布するというアイデアについては考えましたか?
エマヌエーレ: はい。僕たちカイゾク・プレス社としてはそれについて考慮していて、2018年にはニュースをお知らせできます。僕は、僕たちが転換点にいると確信し続けています。紙はデジタルに道を譲りました。その道はまもなくウールに譲られることでしょう。ウールこそが未来です。その間に、僕たちはすでにデジタル配信を開始しており、僕たちのオンラインショップ(http://mutantsandmasterminds.it/ および http://kaizokupress.it/)では、紙でも購入することができます。Drivethrurpg*9 でも購入できます。さらに、Terra dei Giochi(僕たちと提携している数少ないショップのうちのひとつ)では、Webサイト terradeigiochi.it 上で、ミュータント・アンド・マスターマインドのために作られた数多くの素材(公式・非公式ともに)を取り扱っています。また、昨年12月にはイタリアで作られた最初のアドベンチャーが出版されました(無料)。なんとあのLegion (ああ、Legione!懐かしい!)の著者、ダニーロ・モレッティ(Danilo Moretti)によって書かれました。
ルイージ: これからの計画はありますか?すでに作業場に置かれている仕事はありますか?
ミルコ: たくさんのプロジェクト、アイデアだけでなく、他のチームとのコラボレーションや共同制作もあります。カイゾク・プレス社として、現時点では、ジョン・コヴァリック(John Kovalic)によって描かれた『子供たちを食べるコボルドたち』という、ビールとポテトチップから生まれた最初のRPGが作業場に置かれています!その後には、もっと古典的なほうへ移って、M&Mとメガ・アドベンチャーのための一組のエキスパンションと、すでにアメリカで販売されているD&D第5版のためのダンジョン・エポック『Rappan Athuk』の翻訳を行います。端的に言えば、僕たちの名前を信じてください(『Kaizoku』は日本語で『海賊』を意味します)。僕たちは新しい手法の出版で、みなさんを驚かせます(とにかく買って買って、買ってください!できれば、僕たちのサイトで)。
ルイージ: あなたがたのこれからの意欲に感謝を!
出典: https://nerdando.com/2018/02/01/ce-dietro-ledizione-italiana-mutants-masterminds/
*1:クリス・プラマス(Chris Pramas)、グリーン・ローニン(Green Ronin)の代表。RPG以外に食べ物、ウォーゲーム、パンク音楽、ドナルド・トランプとその支持者をからかうことの4つに情熱を燃やしている
*2:訳注: 1990年に発売されたアメコミ
*3:ルッカゲームズ。イタリア最大のアニメ・ゲーム・漫画イベント。年一回ルッカ市で開催される。
*4:イタリアの切手。描かれていたペルーとエクアドル間の国境に誤りがあり、訂正版が印刷された。
*5:ダンジョンズ&ドラゴンズ・スターターキットのこと
*6:ミュータント・アンド・マスターマインド、True20 などのゲームデザイナー。
*7:訳注: 1974年に誕生したダンジョンズ&ドラゴンズのこと。
*9:訳注: RPG関連のWeb通販サイト。http://www.drivethrurpg.com/。
2017年を振り返る
この年齢にもなって恥ずかしながら、自分はとても懐疑的な人間で、それが奏功する場面もあるにはあるのですが、もちろんいつもうまくいくわけではありません。
物事を教わるにしてもそうで、「これこれこういうことが起こらないように、こうするのです」と聞いても、その場では「本当にそうか?それが起きないこともあるのではないか?」と考えがちで、いったん先入観でそうなってしまうと素直に受け入れることができません。
またそういう場合は実感もわきにくく、「そういうこともあるんだろうな」と思おうとしても実際の場面がなかなか想像できないので、いざ直面してみるまでは不測の事態が予期できず、無意識のままに、もしくは楽天的に捉えて、「こうするのです」の部分を破ってしまうことがあります。そしてそのとき初めて「なるほどこういうことが起きないように、こうするのか」と、実感とともに合点がいくのです。
2017年は、とくにそういう年でした。
面白かった本について
小説
『あなたの人生の物語』著:テッド・チャン
- 作者: テッド・チャン,公手成幸,浅倉久志,古沢嘉通,嶋田洋一
- 出版社/メーカー: 早川書房
- 発売日: 2003/09/30
- メディア: 文庫
- 購入: 40人 クリック: 509回
- この商品を含むブログ (392件) を見る
映画『メッセージ』の原作を含む短編集。映画を見てからでも良いので、原作も読むべきだなと思いました。原作ではすこし想像しづらい描写が映像になっていますし、逆に映画での描写の意味が原作での心理描写にあらわれています。より深く楽しめることでしょう。
新書
『日本語 <上・下>』著:金田一春彦
今年は仕事の関係で校正の作業をすることになったので、知識の裏付けの意味もあって日本語関係の書籍をたくさん読みました。そのうちのひとつです。
校正では人の文章に対して少なからぬ提案や指摘をするのですが、その際に「なんか読みにくいから変えてください」とは言えません。多くの場合、説得力のある理由を添える必要があります。この本はその助けになりました。
漫画
とめはねっ!鈴里高校書道部 14 (ヤングサンデーコミックス)
- 作者: 河合克敏
- 出版社/メーカー: 小学館
- 発売日: 2015/05/29
- メディア: コミック
- この商品を含むブログ (20件) を見る
『帯をギュッとね!』や『モンキーターン』を描いた作者による、書道漫画です。テレビドラマにもなりました。1巻から9巻までは去年までに読んでいて、一昨年14巻で完結したことも知っていたのですが、今年になってやっと読み終えました。
近年まれに見る、とても綺麗にまとまった終わり方をした漫画だなと思いました。非現実的なほどに大人びた高校生や、バカで無責任すぎる大人も登場しないし、作者が言いたいことを言うためだけのキャラクターも出てこない。作者が透けて見えないことに、一番好感を持てました。
お酒について
「楽しいお酒を飲む」が今年の目標でした。来年もそのままかなと思います。
年々、飲むと沈むことが増えてきたような気がします。その場は楽しいんですけど。
確定申告について
やりましたが、8ヶ月も前のことでもはや忘れました。最初は freee や MonerForward などのサービスを使ってみましたが、最終的には税務署のWebサイトにあるサービスを使うのが一番楽だったように思います。
そういえば、サービサーとして世の中に何を提供すべきなのかについて考える年でもありました。
よくラーメン屋のたとえ話をしているのですが、世の中にあるものの品質が徐々に下がり、言わば「フードコートのラーメン屋」になっているような気がするのです。それも、看板だけは「老舗の名店」のままで。
するとどうなるかと言うと、少しずつそれが「老舗の出すうまいラーメンの味」として認識されていくのです。もちろん食べた人全員がそう思うわけではないでしょう。しかし味がわかる人だけでないこともまた事実です。
あくまで例え話ですが、ここで言う「老舗の名店」のオーナーが、ラーメンの味がわからないこともまたあります。そんなオーナーが、他の料理人から安価でうまいラーメンを作れると聞けば、今まで雇っていた料理人を入れ替えることでしょう。そしてその安価なラーメンの実態がフードコートのラーメンだとしても、オーナーにはわかりません。
さらに悪いことに、オーナーの店は人通りのある表通りにあり、かつ店の壁に貼られた広告による収入が、ラーメンの販売で得られるそれよりも上回っているのです。多少味のわかる人に幻滅されたとしても、他にも人はたくさんいますし、そもそも人さえ来てくれれば、ラーメンが売れる必要はないのです。
それはもはやラーメン屋なのでしょうか。
そしてそのよくわからない何かは、いったい誰に価値を提供しているのでしょうか。
というようなことを考えたり、悩んだりする年でした。安価で一流のラーメンを作る方法さえあれば、この流れに乗って世の中が良くなっていくと思うのですが、答えは出ていません。
2018年の目標
イタリア語
イタリア旅行を機に今年の8月から勉強しているイタリア語ですが、当然ながらまだまだ身についていませんし、来年も続けます。
今はフレーズ本や単語集を読んだり、勤務中に書籍に付属のCDを聞いたり、Facebook にイタリア語で書き込んだり、NHKの教育番組を見たりしています。来年は、それらに加えて新たにディクテーションをやってみようと思います。
来年の終わりまでには、せめて意味のわかる文を書いたり、多少詰まってでも言いたいことが言えるようになったりしたいなあ。背伸びして翻訳もやってみたい。それにもう一度イタリアにも行きたいなあ。
それではみなさま良いお年を。
イタリア旅行 - 言葉編
イタリア旅行で感じた、言葉についてのことを書きます。
あくまで自分が感じたことにすぎないので、誤りもあると思います。鵜呑みにせず、一意見としてご参考ください。
通じる言語
イタリアの公用語はイタリア語*1です。国家形成の経緯の影響で特徴的な方言が各地方に多くありますが、基本的に全域で共通イタリア語が通じるようです。
そのほか北部でフランスと近い地方ではフランス語が、ドイツと近い地方ではドイツ語が、スイスと近い地方ではスイス語が通じるという話もありますが、自分にはわかりませんでした。
英語は、観光地では基本的に通じますが、日本よりもやや多くの人が話せるかなぐらいの感覚で、挨拶やYes/No、数字、簡単な説明ぐらいであればほぼ全員が話せていたように感じました。少なくとも、ホテルのスタッフや店員さんは全員英語が話せると思って間違いないと思います(バスの運転手さんは怪しいけど)。
とはいえ日本で外国人が「コンニチハ」と言ってくれるとなぜか嬉しいのと同様に、イタリアで「Buongiorno」と挨拶すると嬉しそうにしてくれる人もいます。イタリア語も覚えていったほうが、イタリア人とのコミュニケーションは捗ることでしょう。
最低限覚えたい単語・フレーズ
おそらくどんな言語でもそうですが、以下は最低限覚えて行ったほうが良いと思います。
- ありがとう
- はい
- いいえ
- すみません(呼びかけ)
- ごめんなさい
- おはようございます
- こんにちは
- こんばんは
- またいつか会いましょう
- 美味しい
- トイレはどこですか?
- 1〜20 までの数字
イタリアの場合、「トイレはどこですか?」は非常に重要です。トイレの切れ目が旅の切れ目です。いつでも場所を確認できるようにしておきましょう。上記それぞれのイタリア語は以下です。
- Grazie(グラッツェ) ありがとう
- Sì(スィ) はい
- No(ノ) いいえ
- Scusi(スクズィ) すみません(呼びかけ)
- Mi scusi(ミスクズィ) ごめんなさい
- Buongiorno(ブォンジョルノ) おはようございます
- Buongiorno(同じ) こんにちは
- Buonasera(ブォナセーラ) こんばんは ※15時ぐらいから使う
- Arrivederci(アッリヴェデルチ) またいつか会いましょう ※「さようなら」は Addio(アッディーオ)
- Buono(ブォノ) 美味しい
- Dov'è il bagno?(ドヴェ イルバーニョ?) トイレはどこですか?
1〜20 までの数字は、
- Uno(ウノ) ※同名のカードゲームがありますね
- Due(ドゥーエ)
- Tre(トレ)
- Quattro(クアットロ) ※ピザのクアトロフォルマッジは「4つのチーズ」です
- Cinque(チンクエ)
- Sei(セイ)
- Sette(セッテ)
- Otto(オット)
- Nove(ノヴェ)
- Dieci(ディエチ)
- Undici(ウンディチ) ※Uno + Dieci
- Dodici(ドーディチ) ※Due + Dieci
- Tredici(トレーディチ) ※Tre + Dieci
- Quattordici(クァットールディチ) ※Quattro + Dieci
- Quindici(クィンディチ) ※Cinque + Dieci
- Sedici(セーディチ) ※Sei + Dieci
- Diciassette(ディチャッセッテ) ※Dieci + Sette
- Diciotto(ディチオット) ※Dieci + Otto
- Diciannove(ディチャンノーヴェ) ※Dieci + Nove
- Venti(ヴェンティ)
このあたりは値段でよく聞きました。あとは10刻みで30,40,50...と覚えておいたほうが良いですが、それがなくてもおそらくなんとかなります。
よく使ったフレーズ
最低限覚えておけば良い言葉があれば大丈夫だと思いますが、それ以外にイタリア旅行中よく使ったフレーズを紹介していきます。
クレカ使えますか?
Posso pagare con la carta di credito? (ポッソ パガーレコン ラカルタディクレディト?)
レストランや個人商店、ホテルなどで非常によく使いました。返事は以下のような感じです。
- Certo.(チェルト) =もちろん
- Sì.(スィ) =はい
- No, non accettiamo.(ノー ノナッチェティアーモ) =いいえ、受付できません
これください
Prendo questo.(プレンド クェスト) ※ひとつだけの場合
Prendo questi.(プレンド クェスティ) ※複数の場合
Prendo questa e... questa.(プレンド クェスタ エー… クェスタ) ※「これと〜…これください」と、ショーケースを見ながら考える感じ
黙ってショーケースを指差したり、黙ってレジに持っていっても「買いたい」という意思は伝わりますが、気持ち良い買い物のため、何か一言言いたいものです。そんなときに、自分はこう言いながら買い物していました。ピザ(pizza)などは女性名詞なので、それを指し示すための「これ」も女性名詞形の questa にしてやる必要があったり、厳密に考え始めるとすこしややこしいですが、すべて questo で押し通しても観光客オーラでなんとかなると思います(もちろんきちんと学習したい人はそうはいきませんが)。
ふたりです
Siamo in due.(シアモ イン ドゥーエ)
日常的にレストランやピザ屋に入った際、何人か聞かれるのでこう答えていました。たいてい「ここに座れ」とか「好きな所へどうぞ」とか、手振りと言葉で示してくれます。
予約してます
Ho una prenotazione.(オウナ プレノタツィオーネ) ※イタリア語では「H」は発音しません。
主にホテルのチェックイン時によく使いました。こう言ってから予約票を見せると、スムーズに受付が済みます。しかし同時に、その後の朝食やクリーニングなどの説明もすべてイタリア語で話されてしまうという諸刃の剣でもあります。自信がなければ英語か手振りでいきましょう。
これいくらですか?
Quanto costa?(クアントコスタ?)
たいていのものには値札がついていますが、ときたま値札もシールもついていないことがありました。そんなときにはこのフレーズ。返事は以下のような感じです。
- Dodici.(ドーディチ) =12(ユーロ)
- Venti euro.(ヴェンティエウロ) =20ユーロ
- Dieci e trenta.(ディエチエトレンタ) =10ユーロ30セント
お会計お願いします
Il conto, per favore.(イルコント ペルファヴォーレ)
レストランに入って、座って、メニューを見ながら注文して、食べて…という一連の流れは何も言わなくても済みますが、店を出るときだけは「会計して出たい」という意思を伝える必要があります。そんなときのフレーズがこれ。
ちなみにイタリアではテーブル会計が多かったように思いました。レシートが置かれていない場合でも、店員さんを呼んで上のフレーズを言えば、内訳を記載したレシートを持ってきてくれます。とはいえカウンター払いやレジ払いの店もあるので、周囲を観察するなどしてその店のやり方を見習いましょう。
どれも美味しかったです
Era tutto buono.(エラ トゥット ブォーノ)
レストランのお会計時に言うと受けが大変良いです。美味しかったならぜひ言いましょう。
楽しかったです
È stato un piacere.(エスタート ウンピアチェーレ)
ホテルのスタッフや、路上で絵を描いている人、本屋の店員さんなど、イタリアではたくさんの出会いがあり、その都度会話があります。もし楽しかったなら、別れ際にぜひこう言いましょう。
大人二枚お願いします
Due interi, per favore.(ドゥーエ インテリ ペルファヴォーレ)
美術館や博物館でチケットを買う際によく使いました。intero は「完全な」とかいう意味ですが、子供料金半額などに対し、全額払うという意味なのだと思います。
ここは私の席だと思います
Credo che questo è il mio posto.(クレドケ クェストエ イルミオポースト)
別記事にも書きましたが、長距離列車であるフレッチェは、全席指定席にも関わらず、すでに人が座っていることがしばしばあります(5回中2回ありました)。その際に自分の権利を主張するための言葉がこれです。車両番号に自信がないなど、Credo (クレド 信じる)とまではいかないのであれば、Penso (ペンソ 思う)で言い換えましょう。
持ち帰ります(テイクアウトします)/店内で食べます
Portò via.(ポルトヴィア) =持ち帰ります
Mangio qui.(マンジョクイ) =ここで食べます
信じられないかもしれませんが、意外とマクドに行きます。その際「Mangia qui?(マンジャクイ?)=ここで食べますか?」と聞かれるので、こう答えましょう。
ちなみにイタリアのマクドナルドには、店内にタッチパネル式の自動注文機がある場合があります。ここで注文を済ませ、レシートを受け取ると、品物受け渡し口でレシート記載の番号が呼ばれるという仕組みです。口頭で注文しなくて済むので便利ですが、テイクアウトか店内かの選択だけは、口頭ですることもあります。
この添付ファイルを印刷してもらえますか?
Può stampare questi allegati?(プオ スタンパーレ クェスティアッレガティ?)
イタリア旅行前にすべての予約を済ませ、家で印刷物をプリントアウトしてから出発していれば不要なフレーズですが、急にどこどこの博物館を予約しただとか、帰りの飛行機のWebチェックインをしただとかで、メールで送られてきた予約票や航空券を印刷したくなることがあります。
たいていのホテルは受付で印刷を引き受けてくれるので、このフレーズでメールを見せながら頼んでみましょう。自分は3回ほど経験しましたが、すべて、まずメールをホテルのアドレス宛に転送し、それを印刷してもらう、という流れでした。ホテルによっては1枚1ユーロなどと有料なこともあるので、確認が必要です。
切符(チケット)はどこで買えますか?
Dove posso complare i biglietti?(ドヴェポッソ コンプラーレ イビリエッティ?)
観光地化された教会などに入りたいのに、どこでチケットを買えばいいのかわからないとき、その場で警備している警察官や軍人さんにこう聞いてみましょう。まずどんな人でも指差してくれますし、「Là(ラー)=あそこ」「LÌ(リー)=あそこ」「Sinistra(シニストゥラ)=左」「Destra(デストゥラ)=右」などが聞き取れれば安心です。
荷物を預かってもらえませんか?
Posso lasciare qui i miei bagagli.(ポッソラシャーレクイ イミエイバガーリ)
ホテルのチェックアウトから列車の発車までに時間がある場合、荷物を置いてまだすこし観光したいですよね。そんなときはこう言って確認してみましょう。自分の場合は「ロビーに置いておいて」と言われることがしばしばでした。
ひとつ聞いてもいいですか?
Posso avere un'informazione?(ポッソアヴェーレ ウニンフォルマツィオーネ?)
何か質問したいとき、非常によく使いました。イタリア人の友達が「Un'informazione?」の部分だけで使っていたので真似してそこだけ言っていたんですが、それでも普通に通じたので、後半だけでもいいのかもしれません(少なくとも、変なやつだとか無礼なやつだとか思われているような表情はされませんでした)。
Posso chiederLe una cosa?(ポッソキエデルレ ウナコーザ?)
同じような意味で、こう言うこともできるようです。自分は結局「Un'informazione?」で乗り切ったので、使いませんでした。
手に取っていいですか?
Posso prendere in mano?(ポッソプレンデレ インマーノ?)
お店で陳列されているもので、いかにも壊れそうなものだったり、そもそも触っていいのかどうか迷ったときに、確認のため使いました。
あー良かった。
Meno male.(メノマーレ)
「何か悪いことになりそうだったけど、そうならなかった」というニュアンスの「あー良かった」です。意外に使いますし、これが言えるとイタリア人からニヤッとされます。
これ好きです。
Mi piace questo.(ミピアーチェ クェスト)
例えば料理や絵画など、何かが気に入ったときに積極的に使いました。買い物のときに好みを伝えると、「これが好きなら、これはどう?」とおすすめしてもらえるので助かります。
本当に?
Davvero?(ダヴェーロ?)
相手が言ったことに対するリアクションとしてよく使いました。「Dici davvero?(ディチ ダヴェーロ?)=本気で言ってるの?」などもよく使います。
わかりました。
Ho capito.(オカピート)
相手の説明がわかったら言いましょう。相槌で「なるほど」と言いたいときには、「Capisco.(カピスコ)=なるほど」と言うようにしていました。
(お金を払いながら)これどうぞ
Ecco a lei.(エッコ アレイ)
単に物を渡すときには「Prego.(プレゴ)=どうぞ」が便利ですが、お金を払うときだけは自分はこう言っていました。正しいのかは謎ですが、とくに変な顔もされませんでした。
なぜイタリア語を話すべきか
冒頭で書いた通り、イタリアでは英語が割と通じます。しかしながら、自分はイタリア語を覚えてイタリアに行き、実際に話してみて、できるだけイタリア語で話したほうが良いなと感じました。
それは相手が嬉しそうにしてくれるということもありますが、それ以上に、親しくしてくれるようになるからです。中には、少しだけでも話せることがわかると、こちらが聞き取れるようにゆっくりと、難しい単語を使わず話してくれる人もいます。逆に日本語の簡単な単語を覚えようとする人もいます。こちらが「Buono!」と言うと、誰が教えたのか、「オイシイ!」と笑顔で返してくれる店員さんもいます。そんな人たちとイタリア語を使ってコミュニケーションすることは、きっと感動を伴った忘れられない思い出になるでしょう(自分はなりました)。
少しの努力だけで、旅行がより良い、思い出深いものになるのですから、やはり現地語を覚えて出発するほうが良いと思います。
それに、旅行先で外国語で話すことは、「次はもっと上手くなる!」というモチベーションを高めるためのきっかけをくれます。たいてい、最初はなんでも上手く言えません。自分の場合も、知らない物の名前や知らない用法に直面し、結局は手振りや、まだイタリア語よりは使える英語に頼ってしまうことがしばしばありました。また、ネイティブのイタリア語は全然聞き取れません。これまた「次は完璧に聞き取ってやる」というモチベーションにつながります。たくさん失敗することが、帰国後に学習を継続するための力になるのです。
もちろん「下手なイタリア語で話しおって」とか「最初から英語で言え」とか思われている可能性も大いにあります。とくに自分の仕事をさっさと終わらせたい人が相手だと、その傾向が強いでしょう。しかし、だからといって遠慮していてはいけません。相手はイタリア人ですし、自分が話そうとしているのもイタリア語です。彼らの真似をしてイタリア人らしく己の主義を貫くことに、何の遠慮が要りましょうか。
また、自分は「発音が上手い」としばしば言われました。これは完全にはお世辞ではないようで(部分的にはそうかもですが…)、書籍を当たると「日本人はイタリア語の発音で有利」という記載によく出会います。実際、英語圏出身者のイタリア語で、「cucinare(クチナーレ)=料理する」を「クシナーレ」と発音している人に出会い、聞き取るのに苦労しました。もしかしたらそれは方言だったのかもしれませんが、いっそ「自分のほうがより正しい共通イタリア語の発音をしっかりできてるんだ」と自信を持って発言してしまいましょう。
どう勉強したか
「勉強」というと堅苦しいですが、自分の場合は書籍と、イタリア人の友達に質問するという二つの方法で、旅行前に3ヶ月かけて、少しだけイタリア語を習得しました。
書籍
本屋さんでイタリアのガイドブックと一緒に購入しました。基本の113フレーズと、各フレーズの派生フレーズが収録されていて、音楽にのせて日本語とイタリア語を音読した CD も付属します。
自分の場合は「まずとにかく口で覚えること」を意識して、CDを聞きながら自分でも口ずさみ、覚えにくいものは筆記しながら口に出してみたり、そのフレーズを言いそうな気持ちになって言ってみたり、いろいろやってみました。
仕事中もなるべくCDを聞き、1日1時間は最低限勉強できるようにしました。そのおかげか、3ヶ月の間で、基本フレーズ113のうちの80%ぐらいはスムーズに言えるようになったと思います。
中には「これいつ使うねん」と思うようなフレーズ(「父のためにネクタイを探しています」とか)も入っていますが、そのフレーズに含まれている単語(この場合は「探す」など)が意外に重要だったりと、覚えて損はしない構成かなと思いました。
また、不定冠詞・定冠詞や、数字、曜日、月、代名詞なども掲載されていて、その一覧をそのまま、覚えるまで書き写すことで頭に入れました(だいたい5回目ぐらいで覚えられます)。
デイリー日伊英3か国語会話辞典 カジュアル版
こちらは勉強には使用していません。旅行直前に購入し、イタリアでとても役に立ちました。
27のシーン別にフレーズが合計1,200収録されていて、たいていの言いたいことはこれを見れば言えました。といっても相手の前で堂々と引くというよりは、予め引いて覚えてから言う、という使い方です。
小さめのサイズなので肩掛けバッグの中にも入りますし、いざというときのための保険として忍ばせておくと安心できます。
旅行前に読んだ書籍は、ほとんど上の2冊だけです。もちろんこれだけでは文法や語彙は身につかないので、帰国後に買い足しました。
以上、イタリア語についてでした。思い出し次第追記していきます。
イタリア旅行 - 街の感想(ミラノ・ローマ・ヴェネツィア編)
引き続き、イタリア旅行で訪れた街の感想について書きます。
前編はこちら
ミラノについて
フィレンツェからフレッチェに乗って1時間50分北上したところにあるイタリア第二の商業都市で、北イタリア最大、ヨーロッパ全体でも有数の規模を誇ります。
街にはフィレンツェのように教会や遺跡が数多く残る一方で、高度な近代化が進められており、大通りにはブランドショップが立ち並び、物価も高く、マクドナルドなどの比較的新しい飲食店も数多く建っています。さながら街全体が東京・銀座といった感じを受けました。
街の雰囲気
行く前の印象は『人が密集していて治安が悪く、スリや詐欺師たちが虎視眈々と観光客を狙っている、イタリアで最も危険な街』というものでした。生きて帰れるか割と本気で心配していて、地下鉄に乗るために切符を買うときも周囲を無駄にキョロキョロしていましたし、地下鉄内でも常に必要以上に気を張っていました(必要だった気もしますが)。
しかしながら、いざ実際に行ってみるとそこまでの危険地帯ではありませんでした。身の危険を感じたこともまったくないわけではないですが、北斗の拳の世界ほどではありません。物乞いも他の街に比べると少なかったような気がします。
タクシーに乗っても大丈夫ですし、地下鉄に乗っても身ぐるみ剥がされたりはしませんし、スーパーに武装した軍人は立っていませんし、夜の高速道路を改造バギーが走り回ったりもしていません。日本よりもすこしだけ(地下鉄ではしっかりと)気を張っていれば、きっと快適に過ごせると思います。
余談ですが、自分はアニメ『ロミオの青い空』のファンで、その舞台となったミラノの街には聖地巡礼のつもりで訪問しました。以下の見どころもそれに影響されています。
見どころ
ミラノ大聖堂:ミラノのドゥオーモです。地下鉄 Duomo 駅があり、階段を上がると目の前にその姿が現れます。その時点で感動が押し寄せてきました。ミラノのドゥオーモは14世紀から建設が開始され、宗教改革により一時中断。その後の19世紀にナポレオンによって完成されました。
正面。尖塔群が高画質で見せられないのが残念です。
背面の装飾窓
青銅製の正面扉
側面の装飾
内部。少年時代のロミオはこの光景を見ていない気がします
夕陽を受けるドゥオーモ
夜のドゥオーモ
自分はドゥオーモが好きになりすぎて、一度ならず二度三度と足を運びました。黒い兄弟の誓いのポーズもとってしまいました。内部の装飾も素晴らしく、執念を感じるような緻密さに埋め尽くされており、「そりゃあ信心も持つわ…」と、妙に納得してしまいました。
ドゥオーモの横にはドゥオーモ博物館(Museo Duomo)が併設されており、木造のドゥオーモ模型など、興味深いものがたくさん展示されています。
スカラ座:『ロミオの青い空』作中にて、ニキータがビアンカを見かけたあの場所、スカラ座です。このすぐ横があのマンツォーニ通り(知らんがな)になっていて、意外とすぐそばなんだなあと感じました。
マンツォーニ通り:そのマンツォーニ通りです。そうです。『ロミオの青い空』の中で、ロッシ親方とロミオが「スパッツァカミーノ!(=煙突掃除)」と叫んでいた、あの通りです。おそらく観光マップにはわざわざ載っていません。
通りのはじまり
道幅はおそらく当時のままですが、両側にはブランドショップ、美術館が並んでいます。
ボルゴ横丁:はい、ここも『ロミオの青い空』関連です。マンツォーニ通りを少し歩いて右横に入ると、この小道があります。ロッシ親方の家があった通りです(※フィクションなのでもちろん実際にはありません)。ここも現在はブランドショップやホテルが並んでいて、かつての雑然とした感じ(※フィクションです)はありませんでした。もちろん他の観光客は誰もいませんでした。
サン・バビラ教会:また『ロミオの青い空』です。
賑やかな大通りに面した正面
ロミオとアルフレドとが出会い、アルフレドがロミオに遺志を託したあの教会です(※フィクションです)。残念ながら中には入れませんでした。イメージとは異なり、車通りの多い賑やかな大通りに面しています。すぐ横のビルにはレゴのアンテナショップが入り、逆隣のビルにはブランドショップが入っていました。
レゴでできたドゥオーモ
スフォルツェスコ城:『ロミオの青い空』で、アルフレドが本物の勲章をヴィットーリオ・エマヌエーレ2世の前で掲げ、誇りを取り戻した場所です。
城
星型の城壁の内側は公園になっており、猫たちがえさをもらっていました。
猫の集会
ミラノ警察署:『ロミオの青い空』で、ロミオが信頼されるきっかけとなった事件の舞台です。最初ここに行こうとして、裏手のミラノ警察入国管理所にたどり着いてしまい、近代的な建物を見ながら「あの事件で爆破されてしまって、建て直したのかなあ」などと考えていました(※何度も言いますが『ロミオの青い空』はフィクションです)。実際にはその1本隣の通りにあります。歩道の道幅が狭く、写真がうまく撮れそうになかったので撮影は避けましたが、作中に出てくるのとまったく同じ配色の建物が建っています。
センピオーネ公園:スフォルツェスコ城の北側に広がる公園です。『ロミオの青い空』で、反目しあっていた狼団と黒い兄弟たちが共通の目的のために共闘するという感動スポットです。現在は地元の人や観光客が多くたむろする、さながら代々木公園のような場所になっていて、雰囲気もとても似ています。
Arco delle pace を臨む
公園の夕陽
運河:かつてはミラノにはたくさん運河が通っていたそうですが、現在は埋められ、この運河のみになっているそうです。『ロミオの青い空』的には、ダンテが警察に追われているロミオを助けたり、投げ捨てられてしまったアルフレドの荷物を、ロミオが川に飛び込んで拾うシーンとかで有名でしょうか。
【2018年2月18日追記】
見返したところ、アルフレドの荷物が投げ捨てられ、ロミオが川に飛び込んでそれを拾いに行くシーンは、イタリア・ミラノではなくスイス・ロカルノでのエピソードでした。
夕焼け
運河沿いには書店やBAR、リストランテ、絵画屋などが立ち並び、店外の席でくつろげば、ゆっくり休憩しながら優雅で美しい風景を見ることができます。
カヌーをしている人も
9ユーロビュッフェのお店で食べたこれがおいしかったです
宿泊施設
ミラノでは、治安に不安があったこともあり、四つ星ホテルに宿泊してみました。とはいえ駅から距離があってか一泊の料金は高くありませんでした。むしろ四つ星ともなると、宿泊税が地味に響いてきます…
ホテル・ダ・ヴィンチは、ミラノ中央駅から地下鉄で15分ほどの Comasina 駅から、歩いて15分ほどの位置にあります。ロビーも広く、スタッフも多く、24時間の警備がつき、部屋にはバスタブ(最高!!)やベランダがついていて、さすがの四つ星ホテルでした。
でもピンク色の外壁はどうなんだと言わざるをえない
ホテル内には貸し会議室もあり、ミラノ・マルペンサ空港から近いこと(電車と徒歩でおよそ50分)から、ビジネス用途で宿泊する人も多いようです。
ここで試しにバスタブにお湯を張って浸かってみたんですが、19日にイタリアに到着してから1週間分の疲れが、体からお湯に溶け出すようにして抜けていきました。気持ちよすぎて笑いが出たのは初めてです。やはりバスタブは最高。長旅を、とくに歩きでの旅をする人は、できることなら1週間ごとにお湯に浸かることができるようにしたほうが良いでしょう。足がとろけるかと思いました。
ホテルのスタッフはとても親切で、かといって北イタリアらしく踏み込んでくることもなく、悪く言えばドライ、良く言えばちょうど良く感じるような距離感でした。そういえば若い男性のスタッフから「英語を話したい」オーラを感じることがあったのですが、あれはなんだったのか謎です。もしかしたら「仕事で使うカッコイイ言語」として英語を捉えていて、「それが使える俺、イカす」ということなのかもしれませんが、真相は不明です。
ローマについて
言わずと知れた、イタリアの首都です。紀元前8世紀にその礎を置き、ローマ帝国の首都として、またローマ教皇領時代にはルネサンス文化の中心地となり、19世紀には統一イタリアの首都となりました。街中のいたるところに遺跡・教会・美術館・博物館・昔ながらの市場、近代の建築物が立ち並び、内側にバチカン市国を抱え、古いながらも新しい、ローマの経験してきた各時代の美が調和したような街です。
街の雰囲気
おそらく、イタリアでもっとも空気が汚いです。人も車も多いので、喫煙者の出す煙と車の出す排気ガスが調合され、イタリアの乾燥した空気に乗って、じわじわと肺に襲いかかります。石畳の効果も合わさって、体の外側と内側がまんべんなく疲労します。長時間徒歩で観光する場合は、空気への対策を考えるか、まず長時間歩くことを諦めたほうが良いでしょう。早朝(〜8時頃)はまだ空気がマシなので、そのあいだに移動してしまうのも良いと思います。
人の感じは、フィレンツェほどプライドが高そうではなく、かといってナポリほどおせっかい焼きでもない、ちょうど良い感じです。これで空気さえ良ければ本当にいいのに…
見どころ
フィレンツェ以上に見どころがたくさんあります。おそらく1ヶ月かかってやっと見て回れるぐらいなのではないでしょうか。5日間滞在しましたが、全く足りませんでした。観光スポットの多さは、Wikipedia にもわざわざ個別ページが用意されているほどです。以下には行った場所だけ紹介しますね。
コロッセオ:ローマといえば思い出す人が多いこと間違いなしの、超有名スポットのうちのひとつです。この円形闘技場で剣闘士や猛獣たちが戦い、それを市民に見せることで為政者が己の人気を高めたという施設です。なぜか皇帝ネロによって建設されたイメージがありますが、ウェスパシアヌス帝の時代に作られはじめ、次代のティトゥス帝の時代に完成したそうです。
外観
中には入りませんでしたが、カゼルタで見たカプアの闘技場跡とくらべてとても大きかったです。とはいえ決してカプアのものが小さいわけではなく、こちらのほうが単に遺構が多く、全体として大きすぎるのです。
ちなみにここにはローマ兵のコスプレをしたおじさんがいて、写真撮影と引き換えにお金をせびってきます(詐欺というよりは、そういう商売です)。
このすぐ横にある古代の政治中枢施設群、フォロ・ロマーノも見ました。本当にすぐ横にあるので観光に便利です。
サン・ピエトロ大聖堂:バチカン市国が誇る大聖堂です。思えばローマには、これのほかに巨大な聖堂が無いように感じました。サンタ・マリア・マッジョーレ大聖堂もあるにはあるのですが、フィレンツェやミラノでドゥオーモを見た後なので小さく感じます。ここサン・ピエトロ大聖堂にはミケランジェロの『ピエタ』があるので、それが見たいがためだけに行きました。
朝焼けを受ける大聖堂と聖パウロ像(剣で斬られて死んだので、剣を持っています)
バチカン市国に入るには、広場に直接向かう場合とバチカン博物館から入る場合とがあり、パスポートは不要ですが、荷物検査が必要です。空港の時と同じ金属探知機やX線のスキャナーで荷物を検査され、場合によっては開いて中を見られるようです。大きな手荷物、華美な服装の場合は入国を拒否されてしまうこともあるそうですが、ミニスカ生足のお姉さんは普通に入国できていました。神のご加護かな?
ピエタ像。めっちゃ遠い
ピエタ像は、聖堂入ってすぐ右側に配置されています。しかしミサの日だったからなのか、はたまたテロを警戒してなのか柵が設けられており、写真より近くで見ることは叶いませんでした。バチカン博物館内にレプリカがあるそうなのでそれを見てもいいんですが、自分たちは人が多すぎて見つけられませんでした…。下調べ、超大事。
聖堂内部
天国に行けそうな像(実際、クーポラ・天井へ向かうエレベーターの出口になっています)
「キミなかなか見込みあるねえ」「こんなヤツがッスか!?」
あんなところにどうやって文字を書くんでしょうね
クーポラ。登れます(徒歩5ユーロ、エレベーター7ユーロ)。途中までエレベーターを使って登っても、かなり疲れます
アイドル(偶像)たちの背中
聖ペテロ像。天上へ入るための鍵を持っています
この日はちょうど、11時にローマ法王が顔を出す日でもあり(毎週日曜日)、10時頃までには広場に続々と人が集まっていました。
ポルタ・ポルテーゼの蚤の市:ローマの旧市街、トラステヴェレ地区にあるポルタ・ポルテーゼからポルトゥエンセ通り、それに続くエットーレ・ロッソ通り、イッポリト・ニエヴォ通りに長々と伸びる、長大な蚤の市です。売っているものは日用品・本・衣料品・サングラス・カバン・食料品・古物・家具・絵画・文房具などなど多種多様で、なんでも雑多に安く売っています。人混みが多いだけにスリも多いらしく、注意が必要な場所でもありますが、初めて見るその土地ならではのものに出会える場所でもあり、とても楽しめました。
蚤の市と曇り空
金物屋さん
ナルトの懐中時計(ハガレンのもありました)
バチカン博物館:ローマ教皇が500年間かけて集めたり作らせたりした、名品珍品たちが所狭しと立ち並ぶ博物館・美術館の集合体です。何と言っても有名なのは、システィーナ礼拝堂の天井絵(ミケランジェロ『アダムの創造』、『原罪と楽園追放』など)や、『最後の審判』ですよね。超有名博物館のため、入場に長蛇の列ができます。自分の場合は2時間待ちました。スケジュールが決まっている場合は、必ず予約しておきましょう。4ユーロ払うだけで2時間待ちの列が飛ばせます。2時間待つことを考えると、めちゃくちゃ安いです。
壁に沿って長蛇の列ができる(これで半分)
もう半分はこちら
予約している場合は列を飛ばしてここまで来ることができます(この左隣りが入場口)
システィーナ礼拝堂内は写真撮影が禁止されています(それでも堂々と自撮りしている人はいましたが)。また、見たいものがどのエリアに置かれているか、位置と場所のイタリア語名(英語名でも良いかも)を事前に調べておくと良いでしょう。なにせ人でごった返すのでとにかく疲れてしまい、一度進んでから戻るという選択肢が取りづらい場所です。順路もいくつかありますし、とくにラファエロの『アテナイの学堂』や、古代ローマの『ラオコーン群像』が見たい場合は道順や見る順序に気をつけましょう(自分は見逃しました)。
ちなみに出口付近にはフードコート形式のピザ屋が入っており、ポテトとピザのセットなどが注文できます。お値段はたしか10ユーロぐらいだったと思います。
トレヴィの泉:バロック時代の人工噴水、コインを後ろ向きで投げるあの場所です。早朝7時頃に掃除が行われ、その間は近づくことができないそうで、その間に前日に投げ込まれたコインもまた回収されています。細い路地を過ぎたところに急に泉が現れるので、唐突感がありました。じつはここを訪れた日のわずか5日前に、泉が赤く染まる事件が起きたばかりでした。
参考:ローマの観光名所「トレビの泉」が真っ赤に 男が染料を投入 - シネマトゥデイ
そのためか警備が非常に厳重で、柵も張り巡らされ、近くに寄ることはできませんでした。
投げるなとは書かれていなかったので、ちゃんとコインは投げてきましたけどね
スペイン広場:『ローマの休日』で、ジェラートを食べているオードリー・ヘップバーンを、グレゴリー・ペックがローマ案内に連れ出す場所です(たしか)。
上からの様子。意外に人はまばら
階段に腰掛けて通りや観光客たちを眺めているだけで、良い休憩になります。
パンテオン:古代ローマの万神殿、パンテオンです。128年に再建されたものが現代にまで残っている建物で、後にキリスト教聖堂となりました。偉大な芸術家ラファエロの墓があります。
荘重な外観
天井
ラファエロの墓
広場にあるオベリスク
MANGASIA:観光名所というわけではないのですが、ローマのエスポシツィオーニ宮で、アジアの漫画展『MANGASIA』が開催されていたので、見てきました。
MANGASIA
中国の漫画誌
江戸時代の浮世絵と、現代の子連れ狼
ゲンの生原稿を初めて見ました。なぜかローマで
ここだけ日本なのかもしれない(自由に読めます)
手前から『地球へ…』、『攻殻機動隊』、『犬夜叉(愛蔵版)』、『GreatMechanicsDX 9』、『進撃の巨人 1巻』
初音ミクのライブ映像
AKIRA のセル画(目に焼き付けてきました)
このほか、Kinect のような仕組みで自分の体に連動して動く、巨大ロボット映像の展示もあり、奥さんが夢中で遊んでいました(かわいい)。
宿泊施設
ローマでは二つ星の、ホテル・イタリアに5泊しました。
最初は、玄関がどこにあるのかわからず、ようやく探し当てたドアの開け方もわからず(集合チャイムのホテルのボタンを押すと玄関ドアが開きました)、二つ星らしく部屋の設備もお世辞には良いとは言えなかった(お風呂が非常に狭い)ので、正直「旅の最後にやらかしたかな」と思っていました。
しかしながら、このホテルのスタッフのフレンドリーさからはいわゆる「ナポリっぽさ」が垣間見え、とくに中年のスタッフに対して、こちらが「Quarantaquattro, per favore.(44番、お願いします ※部屋のカギ番号)」と言った際の、「イタリア語がとても上手ですねえ〜。どうやって勉強したんですか?(イタリア語)」という嬉しそうな笑顔が忘れられません。
このスタッフとはその後も何度も話す機会があり、ホテル近くで持ち帰りができるおいしいピザ屋さん(Ristorante Strega)を教えてもらったので、そのお礼にビールをプレゼントしたり、おじさんが嬉しそうに「日本語を覚えた。ヨンジュヨン〜(44)」と話してくれたり、おじさんの奥さんや子供さんたちの写真を見せてもらったりと、とても仲良くなれました。
二つ星なので宿泊税も安めに抑えられましたし(5泊2名で3x5x2=30ユーロ)、ホテルの位置が観光にとても便利でしたし、20時まで開いているスーパーがすぐそばにありますし、結果的にここにして良かったと満足できました。
おじさんは別れ際に「今度ローマに来るときには連絡してくれ」と言ってましたし、いつかまたここに宿泊すると思います。
六甲
宿泊施設ではなく飲食店ですが、六甲も紹介します。こちらは日本人オーナーが経営している日本料理店で、スペイン広場やサンタンジェロ城のすぐそばにあります(地図)。
ローマに滞在しはじめたのは、イタリアに入国してから10日目のことでした。さすがにイタリア料理にも飽き始め、「そろそろお味噌汁が飲みたい」という欲望が抑えきれなくなってきていたのですが、その一方で、それまでに怪しい日本料理店しか見つけられておらず、また「せっかくイタリアにいるのに」という思いもあり、あえて調べることはしていませんでした。しかしその後結局「四の五の言ってられるか。今すぐ白い飯を出せ」となり、検索して探し当てたのがここです。
安心する店内
安心するメニュー(頑張らなくても読めることに違和感がありました)
安心する箸とお茶
安心するカツ丼
味は日本風そのもの。お味噌汁も嬉しく、思えばイタリアに来てからイタリア料理でもスープを口にしていなかったことに気が付きました(スープ料理が無いってことはないと思うのですが…)。お茶が甘くないことも嬉しさに拍車を駆け、すごい勢いで丼をかきこみ、気がつけば完食していました。
ここのお米は日本でお馴染みのあきたこまちなのですが、なんとイタリアの契約農家に栽培してもらっているものらしく、そのこだわりのお米は一粒一粒しっかりとした甘みがあり、とても美味しかったです(ちゃんと味わって食べましたよ!)。
みなさんももしローマで日本食が恋しくなったら、こちらの六甲を思い出してください。日本の味が待っています。
ヴェネツィアについて
さて、最後はヴェネツィアです。ミラノから列車で2時間40分、フィレンツェからは2時間10分の位置にある、水上都市です。
しかし自分の場合はローマから行ったので、片道4時間・往復8時間もかかってしまいました。ギリギリ日帰りはできましたが、疲れるのであまりおすすめしません。フィレンツェやボローニャから行くのが、一番手軽かと思います。
街の雰囲気
ディズニーシーです。ディズニーシーがヴェネツィアやフィレンツェをモデルにしているのだと思いますが、入り口のお土産屋が全域に拡張され、全体的に広くなった、ディズニーシーでした。テーマパークのようでいて、地元民の生活感もあり、不思議な空間です。人の特徴はつかめませんでしたが、基本的にホスピタリティのある人が多かったように感じました。
陸にある Porto Marghera(ポルト・マルゲラ)駅からSanta Lucia(サンタ・ルチア)駅へ向かう橋の上
見どころ
サンタ・ルチア駅前:列車を降りるとそこは、いきなり運河です。「これ見に来たんだろ。ほい」という感じで、いきなり運河が広がっています。「ああ、水の国に来たんだな」と強制的に実感させられます。ここからは水上バスに乗るか、徒歩で歩き回るかを選ぶことができます。自動車の乗り入れが禁止されている(そもそも車道が無い)ので、タクシーはいません。
広場と運河
橋の上から見た運河と駅。右の建物は水上バスの停留所
運河の端に腰掛けての光景
街並み:歩くだけで絵になる風景に出会えるのがイタリアですが、ヴェネツィアはとくにそうで、水面に映る景色と街並みが織りなす光景は、ここ特有のものです。
ほらまたそうやってすぐ絵になる〜〜〜〜
運河とゴンドラ
夕陽と街並み、そして運河
サン・マルコ大聖堂:9世紀にイタリアの各都市が聖人にちなんで箔を付ける中、「うちも乗り遅れてはおれん!」ということで聖マルコの聖遺物を入手し(盗品です)、安置するために建てられた聖堂です。
聖堂正面
サンマルコ広場に面しており、広場のいたるところに聖マルコの象徴である有翼の獅子像が建っていました。
有翼の獅子像
ドゥカーレ宮:8世紀に建設された、ヴェネツィア共和国の政庁兼総督邸です。現在中は美術館になっているそうです(入りませんでした)。
広場側
海側
溜息橋:ドゥカーレ宮と牢獄とを結んでいる橋で、「宮殿で有罪判決を受けた囚人が、この橋を通る際に窓から外を見て溜息をつく」という19世紀の詩から名付けられたそうです。
ため息橋とゴンドラ
宿泊施設
ヴェネツィアには日帰りしたので宿泊しませんでした。そもそもヴェネツィアは物価が高めで、宿泊料金も他の都市に比べてお高いようです。
それからヴェネツィアに宿泊する場合、駅からホテルへの移動手段について考える必要があります。というのも、タクシーがいないからで、つまり荷物を持ったまま移動する手段が限られるからです。徒歩で頑張ってもいいんですが、橋を渡ったり狭い路地を通ったりする必要があります。そんな人のために駅前には荷物運び屋がたくさん待機していますが、スーツケースひとつあたり20ユーロほどもするそうです。うーん、高い。なるべく駅から近いホテルをとるのが得策でしょう。
最後に、またイタリアへ行くとしたら
イタリアで6都市を旅して、さんざん「空気が悪い」と書いてきましたが、帰国後しばらくして、「またイタリアに行きたい」と思っていることもまた事実です。
南イタリアにはナポリ・カゼルタにしか行っておらず、さらに南のバーリやシチリア島には行っていませんし、中央イタリアのサルデーニャ島にも行ってみたい気持ちがあります。ヴェネツィア・フィレンツェ・ローマの博物館・美術館にはまだまだ見てみたいものもありますし、ミラノのドゥオーモも、生きている内に再訪したい。何よりローマには仲良くなったおじさんがいるので、また行かなければなりません。
それに当たって、次また旅をするとしたらどうするか、以下に残しておきます。
より上手なホテルの決め方
- Booking.com のレビュースコアが8.5点以上あること
- 早朝に見たい施設のすぐ近くにあること(※ただしヴェネツィアでは例外で、駅近くのほうが良い)
- がっつり休みたくなるタイミングには、設備が良いホテルに泊まること(バスタブは必須)
- 星が多すぎないこと
ミラノでは、もう少し Milano centrale 駅の近くでも良かったかなと感じました。奇跡的に友達の家まで歩いて15分ほどだったのでその点は良かったのですが、市街地に出るまでに地下鉄で20分ほどかかり、観光にやや不便さを感じました。観光旅行は限られた時間と体力との勝負なので、観光スポットの近くであることにこしたことはありません。まあ、そのぶん高くなるんですけどね…。
より上手な移動方法
- バスを使う
地下鉄が全域に整備されているわけではないので、次行く際にはバス停の位置を地図で用意しておき、バスを乗りこなせるようにしたいと思いました。フィレンツェでは絶対に先に切符を買います。
より上手なスケジュールの決め方
今回の旅行ではスケジュールにあえて不確定要素を作り、「旅行中に決めればいいか」としていた部分が多くありました。その結果、ローマから日帰りで8時間かけてヴェネツィアに行ったり、予約なしでバチカン博物館へ行くことになってしまったので、このあたりはやはり事前に調べてきっちり決めておくなり、予約しておくなりしたほうが良かったなと感じました(ハプニングも旅の醍醐味ですけどね!)。
そんなこんなでいろいろとありましたが、全体的に楽しく旅ができたので、イタリアに大満足でした。
イタリア旅行 - 街の感想(カゼルタ・ナポリ・フィレンツェ編)
イタリア旅行で訪れた街の感想について書きます。
行った街と全体的な感想
下の記事にも書きましたが、カゼルタ・ナポリ・フィレンツェ・ミラノ・ヴェネツィア・ローマに滞在しました。ヴェネツィアは日帰りしたので滞在と呼べるかどうかわかりませんが、少なくとも足は運びました。
イタリアは北・中央・南に分けられますが、北が都会で、南に行くほど田舎になる印象を受けました。北にある都市から順に日本で例えるとすれば、北イタリアが関東、南イタリアが近畿で、その間に都市が分布している感じです。
ナポリからさらに南には行っていないのでわかりませんが、これでいくと、きっと広島や九州っぽい感じなのかもしれないなと思っています。
カゼルタについて
ナポリから列車でおよそ40分の位置にある都市で、ナポリ王国の宮殿であるカゼルタ宮殿や、イタリアで二番目に大きい闘技場跡や、旧市街であるカゼルタヴェッキアなどがあります。
地図ではこのあたり
街の雰囲気
南イタリアの気質なのかもしれませんが、だいたいの人がおせっかい焼きで優しく、純粋で、心の距離が近く感じました。
チケットを買わずに遺跡に入っていこうとすると、わざわざ売店から走って出てきて「先にチケット買わなきゃダメだよ!」と言ってくれるし(その人が注意しなくても、その先でチケットを確認されるのですが、距離があり手間になる)、カゼルタ宮殿前の広場でぼんやりしていると「ここは入り口じゃないよ。入り口はあっち」とおじさんがぶっきらぼうに教えてくれるし、ピザ屋(Pizzeria)で一度座った席が騒がしかったので、店員さんに席を移っていいか聞くと、ナポリ弁で冗談交じりに「自分が好きで座った席だろ!?」と言われるし(カゼルタ出身の友達が聞いたからだと思います。席も普通に移動できました)、通りでおばあさんに「ニイハオ」と話しかけられるし…。語り尽くせませんが、すごくたくさんの人に話しかけられました。
地方都市らしく駅前が多少寂れてはいますが、中心部は賑やかで、オシャレなBARやピザ屋、ブランドショップなども多くあり、平日の昼間でも広場のカフェ(BAR)に人が溢れているなど、活気があります。近年若者が多く集まるようになっているらしく、夜の賑わいもなかなかのものでした。ワインバーは若者だらけでしたし、土曜日の夜なんかはホテルの外でデモでも起きているのではないかと思うぐらいの騒がしさでした。
見どころ
カゼルタ宮殿:18世紀に世界で建設されたうちで最大の宮殿であり、世界遺産。ナポリ王国の宮殿として1752年に建設が始められ、1780年に完成しましたが、その後1799年にナポリ王国はナポレオンによって占領されてしまいました。ヴェルサイユ宮殿に影響を受けており、とくに公園はヴェルサイユ宮殿以上の評価を得ているそうです。映画のロケ地として使われることも多く、『スターウォーズ』ではアミダラ女王の居城として登場し、『アマルフィ』や『MI:3』『天使と悪魔』にも使用されました。
大階段
宮殿前広場
ディアナとアクタイオン像
英国風の植物園
カゼルタ宮殿は公園・内部ともにとても広大で、一日ですべて見て回るのは難しいぐらいに展示物がたくさん置かれていました。また18世紀の物品以外にも、2016年までイタリア軍が使用していた空間を利用して、現在は近代美術の展示(アンディー・ウォーホルやキース・ヘリングなどの作品展示)が行われています。
カプアの闘技場跡:あのスパルタクスらが戦った闘技場跡。イタリアで二番目に大きな闘技場跡で、近くにはあのアッピア街道も通っています。つまりここで反乱の声を挙げたスパルタクスが、敗北後に磔にされたのもまたここということです。それだけで自分は大興奮でした。
闘技場跡
闘技場地下
カゼルタヴェッキア:カゼルタの旧中心街。古い町並みが現在にも残っていて、カゼルタ城やドゥオーモなどがあります。自分たちは夜に行ったので、カゼルタ城の全景を捉えることはできませんでしたが、美しい夜景が見られました。
ナポリ方面を見た夜景
ドゥオーモの一部
古い街並み
宿泊施設
カゼルタ宮殿のほぼ真横に位置する、Cas'E charming house に宿泊しました。
Booking.com でのレビュースコアが9.8(上限は10)もあり、かなり期待して訪れましたが、期待通りというよりは期待以上の場所でした。
スタッフが非常にフレンドリーでホスピタリティに溢れ、部屋の設備は完璧とは言わないまでも細かな心配りが効いていて、アメニティは豊富に用意されており、かつ清掃が行き届いており、朝食も気持ちよく食べることができましたし、カゼルタは宿泊税もかかりません。何の文句もありません。自分にとっては文句なしの10点満点です。手放しでおすすめできます。
21時以降にスタッフがいなくなるので、深夜にチェックインがしたい人には不都合があるかもしれません。また、バスタブが無いことが気になる人もいるでしょう(イタリアではバスタブがあるほうが珍しいように感じましたが)。それから日本語は一切通じません。
自分はここに宿泊したおかげもあって、カゼルタが好きになりました。ここに泊まってもっとイタリアを知るために、いつか再訪したいと思っています。できればいつまでも滞在したいなあ。
ナポリについて
ローマからフレッチェで1時間20分。古代ギリシアの植民市「ネアポリス」に端を発する、イタリア第3の都市(ローマ、ミラノに次ぐ)。街中に突然ローマ時代の石材を利用した建築物(現在は違法行為)が現れたり、とても活気のある商店街があったり、移民の多い場所であったりと、とても渾沌としている。
このあたり。南イタリア最大の都市。
街の雰囲気
とても大阪っぽい場所。とても人口が多く、かつ人と人との距離は近く、物価は安めで(ミラノの三分の二か半分ぐらい)、マフィアがいて、すごく活気があって、治安も悪めと、とても大阪っぽい場所(二回目)でした。
ミラノ中央駅から市街地へ向かう道では両側に商店や露店や詐欺師(ギャンブル詐欺)が取り囲み、商店のすぐそばにもイタリア人の友達曰く「あの人は一度刑務所に入った人だと思う」(入れ墨でわかるそう)というような人がたむろしていたり、活気と危険が相混ざっています。
ハプニングや知らない物事に触れられてとても楽しめる街だと思いますが、その一方でふと犯罪に巻き込まれる可能性もあるような印象を受けました。防犯に気をつけつつ、しかしながら萎縮しすぎずに街を楽しむのがちょうど良いと思います。
見どころ
ナポリは古い街だけあって、いたるところに古代ローマ時代の遺物や中世の教会建築、地下遺跡などが点在しています。そうでなくても、現代に暮らすナポリの人たちが作るたくさんのイベントや見世物、路上の大学(卒業してきました)などがあり、1日ではとても見きれません。
卵城:ローマ帝国時代に建設された別荘が、11世紀以降に要塞化された建物です。なぜ卵かというと、この城のどこかに卵が埋められており、「その卵が割れる時、ナポリもまた滅びるだろう」という伝説が残っているからなのだそう。奥さんが「卵を見つけて目玉焼きにする!」と息巻いていました(かわいい)。
卵城
ここからの夜景は本当に美しく、「ナポリを見て死ね」という言葉に納得でした。
ヌオヴォ城:Nuovo(ヌオヴォ)は「新しい」という意味。中までは見ませんでしたが、城門に砲弾の跡が今も生々しく残っています(外観の写真を撮り忘れました)。
ナポリ王宮:17世紀に建設された宮殿。ナポリ王国の宮殿で、このあと18世紀後半にカゼルタ宮殿が作られたのでしたが、まもなくナポリ王国は滅びてしまいました(こちらも写真を撮り忘れ…)。
古代ローマ時代の遺物を(勝手に)使った建物:観光資源ではなく個人宅ですが、かつて古代ローマ時代の建物に使われていた廃材を、勝手に拾ってきて使った建物が今も使われています。現代では違法行為ですが、かつては遺跡があまり重要視されていなかったので、セーフだったのだとか。
街角で急に現れます
宿泊施設
ナポリにはカゼルタから行ったので、宿泊はしていません。
フィレンツェについて
言わずと知れたメディチ家のお膝元。市街中心部全体が世界遺産に指定されている古都です。冒頭にも書きましたが、どことなく京都っぽいなと思いました。
このあたり。北イタリアです。
街の雰囲気
良くも悪くも京都。観光地ですから、ビジネスライクな人当たりはとても良かったです。古い街であることのプライドも高く、住民もそれを誇りに感じていることが強く感じられました。ナポリやカゼルタほど人情が感じられず、それでいておせっかいすぎず、観光客には滞在を楽しんでほしい!(でも住むのは覚悟してからにしろ)という感じの場所です。
街は全体が世界遺産に指定されているだけあって古く、道はどこも狭めで、建物からの細かなチリが空気の乾燥に拍車を駆けています。こう言うと微妙な感じがしますが、街の景色やミケランジェロ広場などから眺める風景は最高でした。川辺は開けていますし、開放感もあります。
見どころ
フィレンツェはとにかく見どころが多すぎます。どこを見ても遺産・遺産・博物館・美術館・遺産の連続。2日間滞在しましたが、すべて見て回るには全然足りません。体感ですが、1週間でも頑張ってギリギリ回れるか回れないか、ぐらいなのではないでしょうか。
アカデミア美術館:ミケランジェロのダビデ像がある美術館です。入場には長い列が作られますが、予約をすることでスキップすることができます(自分はたしか30分ほど並びました)。並んでいるあいだに奥さんがいらない紙で鶴を折ったところ、前に並んでいた若い女の子が目を丸くしながら「Bello…! =きれい・すごい」と呟いていて、「まだ折り紙で喜んでくれる外国人はたくさんいるんだ」と感動しました。
折り鶴
Love, vice and wisdom
そのほかにもたくさんの彫刻・絵画が展示されています。ダビデ像は自分で見たほうがいいと思うので、ここには掲載しません。
ドゥオーモとクーポラ:サンタ・マリア・デル・フィオーレ大聖堂とそのクーポラは、フィレンツェの街並みに取り囲まれるようにして建っています。白・緑・ピンクの大理石で美しく彩色されており、そのクーポラに登ると、フィレンツェの街が一望できます。ただし、かなり高所になり柵も高くはないので、高所恐怖症の人にはおすすめしません。
通りから覗くクーポラ
聖堂正面
クーポラから見下ろした街並み
ヴェッキオ宮殿:映画『インフェルノ』でキーアイテムとなるダンテのマスクが展示してあります。その他にも映画の中に登場した部屋や絵画などを見て、「あーあそこから落ちてきたんだよね」とかなんとか盛り上がれる場所です。
『あの部屋ね』となること間違い無しの、500人大広間
ダンテのデスマスクと一緒に写真撮影すると、なんとも不思議な気持ちになりました。ちなみにここにもダビデ像はいます(レプリカ)。
ミケランジェロ広場:サンタ・マリア・デル・フィオーレ大聖堂から南へ歩いて30分の高台にあり、フィレンツェの街全体が見渡せる大きな広場です。徒歩で行ってもいいですが、バスで行くほうが体力的に安全です。特に見晴らしの良い角の場所は、セルフィーを撮りたい観光客がちょっとした列を作っていました(並びました)。
広場からの眺望。この少し横に、もっとよく見える場所があります。
ダビデ像(レプリカ)
宿泊施設
フィレンツェの中央駅、サンタ・マリア・ノヴェッラ駅から徒歩20分ほどの場所にある、ホテル・アストロ・メディセオに宿泊しました。
美しい内装と、行き届いたサービスがすばらしいホテルでした。スーパーで買ってきた食べ物を「これ温めてくれませんか」と頼んでも、嫌な顔ひとつせずに引き受けてくれ、滞在が快適になるような心遣いに富んだスタッフさんたちがいました。1階にディナーが食べられるレストランがあり便利ですし、そこで供される朝食も、とても美味しかったです。
駅からすこし距離がありますが、たしかタクシーでも10ユーロほどだったと記憶しています。歩いて1分もしないすぐ近くに12番のバス停もあり、12番は駅から乗ることもできるので、それを利用しても良いと思います(売店で切符を先に買うのをお忘れなく)。
当初の予定よりも長くなってしまったので、記事を前後編に分けようと思います。
後半のミラノ・ヴェネツィア・ローマ編をお楽しみに。
(追記)後編書きました。