複数のテーブルに基づくクエリ

 さて、これまでの節では、クエリに1つのテーブルを置き、そこから必要な行や列を抽出したり、計算により導いた列(演算フィールド)を作成する例を示してきました。
 しかし、クエリデザインの画面に置けるテーブルは1つに限られません。2つ以上のテーブルを置くこともできます。
 そこで、ここではまず2つ以上のテーブルを置いたときにどのようなデータが表示されるのか、また、それをもとにしてどのようにデータを取り出すことができるのかについて、簡単な例を示します。
 複数の表を組み合わせてデータを取り出す、というのはAccessが最も得意とする分野です。Excelでも可能ではありますが、照合関数を多用するなどかなりの手間がかかります。Accessでは対象となる列と条件を指定するだけで容易にデータを取り出すことができ、Excelでは困難なケースにも比較的簡単に対応できます。

f:id:accs2014:20170625001533p:plain:right:w500

 まず、2つのテーブルを置いた場合にどのようなデータが表示されるのかを見てみましょう。
 例として用いるのは、ある会社の「社員テーブル」と…


f:id:accs2014:20170625001530p:plain:right:w500

 同社の「商品テーブル」です。
 内容を見るとこれらのテーブルには直接的な関連がありませんが、あえてこの2つのテーブルを用いて、どのようなデータが表示されるか見てみます。


f:id:accs2014:20170625001526p:plain:right:w600

 クエリデザインの様子です。2つのテーブルを置き、単純にすべての列を表示させてみます。


f:id:accs2014:20170625001518p:plain:right:w550

 データシートビューです。
 さて、指定したすべての列が表示されているのは間違いありませんが、行がやたらと多く表示されています。
なぜこうなるのかといいますと、クエリデザインに2つのテーブルを置いた場合、「2つのテーブルにある行(レコード)のすべての組み合わせを表示する」という仕組みになっているからです。社員テーブルには5つの行、商品テーブルには6つの行がありますので、5×6=30行のデータをもつクエリが表示されているというわけです。
このような、すべての行の組み合わせのことを「直積」と呼びます。実際のところ、この言葉を使うことはあまりありませんし、このようなすべての組み合わせのデータを必要とすることもあまりないだろうと思われます。
 しかし、クエリデザインに複数のテーブルを置いた時点でこのようにすべての行の組み合わせが発生するということは重要なポイントです。Accessで複数のテーブルからデータの抽出を行うとき、まずすべての行の組み合わせのデータ(直積)を発生させ、それに対して条件を課し、必要なデータを絞り込んでいくという流れ(仕組み)になります。実際にはいちいち直積の内容を見ながら進めていく必要はないのですが、この後で見るデータ抽出の結果がなぜそうなるのかピンと来ない場合は、まずこの流れ(仕組み)を思いだし、取り出されるデータをイメージしていただきたいと思います。


f:id:accs2014:20170625001513p:plain:right:w600

 さて、この2つのテーブルの内容には直接的な関連がありませんが、かといって意味のあるデータの抽出が全くできないというわけではありません。
デザインビューに戻り、「発売日」列の抽出条件欄に「<[生年月日]」と記入します。これにより、先ほど見たすべての組み合わせの中から「商品の発売日が社員の生年月日より古い」という条件を満たすものを取り出すこととなります。


f:id:accs2014:20170625001613p:plain:right:w600

 データシートビューです。これにより、それぞれの社員が、自分が生まれる前から販売されている自社商品が何なのかを知ることができます。


f:id:accs2014:20170625001610p:plain:right:w400

 別の例を見てみます。同じ会社の「部署テーブル」と…


f:id:accs2014:20170625001608p:plain:right:w500

 先ほども見た「社員テーブル」の2つです。どちらのテーブルにも「部署コード」という列があります。これにより、どの社員がどの部署に勤務しているのかがわかります。
 この2つのテーブルからクエリを作ってみます。


f:id:accs2014:20170625001604p:plain:right:w600

 デザインビューです。まず2つのテーブルを置きます(画像は省略しますが、この時点で、3×5=15行の「直積」が発生します)。
 そして、社員テーブルの「部署コード」の抽出条件欄に「=[部署テーブル].[部署コード]」と入力します。これで両方のテーブルの「部署コード」列が等しいものだけが抽出されます。

 なお、最初の例と同じく「単純にテーブルを2つ置いた」という状態を表すため、テーブルに対しリレーションシップの設定を行っていません。リレーションシップの設定を行っている場合、2つのテーブルを置いたときに2つのテーブルをつなぐ「線」が表示され、抽出条件の入力を省くことができます。具体的な例は下記にて示します。


f:id:accs2014:20170625001601p:plain:right:w550

 データシートビューです。抽出されるデータは5行となります。社員テーブルの1つの行に1つの「部署コード」が記録されており、これが部署テーブルの1つの行に対応しているので(つまり1人の社員は1つの部署にのみ所属しているので)これは直感的に理解しやすいものと思います。
 さて、クエリの内容は、それぞれの社員の情報と、それぞれの社員が属する部署の情報を一体的に表示したものとなります。このように「両方のテーブルにある、同じ値に基づいてデータを取り出す」というのはとても基本的で重要なデータ抽出の方法ですが、Excelですと参照しようとするシートの列番号を数えてVLOOKUP関数を入力して…と結構な手間がかかるところです。Accessでは表示するテーブルと列を選び、抽出条件を指定するだけで実現できますので大変便利です。


f:id:accs2014:20170625001651p:plain:right:w500

 さて、Accessではこの「両方のテーブルにある、同じ値に基づいてデータを取り出す」というデータ抽出を、さらに簡単な操作で行うことができ、これを「(内部)結合」といいます。

 実際にやってみます。2つのテーブルを置いた状態で、結合の対象となる列名の一方をクリックし、もう一方の列に向かってドラッグします。


f:id:accs2014:20170625001647p:plain:right:w600

 両方の列名の間に線がひかれました。
 これにより「両方の列の値が同じである行を取り出す」という条件を指定したこととなります。検索条件欄に何も記入していないことを確認してください。


f:id:accs2014:20170625001642p:plain:right:w550

 データシートビューです。上記の例と全く同じ、5行のデータが得られています。
 「(内部)結合」の結果は、検索条件欄に記入して抽出した場合と同じですが、操作の簡単さもあって通常はこちらが用いられます。
 また、上記のように、双方の列の間にリレーションシップの設定を行っている場合、「線」は自動的に表示されます。つまり、「両方のテーブルにある、同じ値に基づいてデータを取り出す」という条件が自動的に設定されます。