Accessクエリでテーブルを結合する方法 内部結合と外部結合

概要

この記事の結論
Accessのクエリでは、2つのテーブルを共通のIDで結び、必要な列をまとめて表示できます。両方に一致するデータだけを見るなら内部結合、片方を全件残すなら外部結合を選びます。ただし、一方のIDが複数行に登場すると、結果の行数も増えます。結合線を引くだけで終わらせず、キーの意味とデータ型、結果の件数、抽出条件で消える行まで確認することが、正しい一覧や集計につながります。
テーブルの結合とは、共通する項目を条件に、別々の表の行を対応付けて1つの結果として取り出す操作です。

この記事でわかること

  • 共通キーとサンプルテーブルを準備する
  • デザインビューで結合クエリを作成する
  • 外部結合で消える行とNullを確認する
  • 件数増加と二重集計を防ぐ

この記事の主な内容

  1. 内部結合と外部結合を目的で選ぶ
  2. 共通キーとサンプルテーブルを準備する
  3. デザインビューで結合クエリを作成する
  4. 外部結合で消える行とNullを確認する
  5. 件数増加と二重集計を防ぐ
  6. 複合キーと運用前の確認
  7. よくある質問

想定読了時間:約15分~20分


内部結合と外部結合を目的で選ぶ

Accessで別々のテーブルから情報を取り出すには、共通するIDなどで行を結びます。例えば顧客テーブルに顧客名、注文テーブルに注文日がある場合、顧客IDで結合すれば、誰がいつ注文したかを1つの一覧で表示できます。元のテーブルを物理的に1つへ統合する操作ではありません。

どちらの行を残したいかを先に決める

内部結合は、両方の表で条件が一致する組み合わせだけを取り出します。外部結合は、一方の表を全件残し、相手側に一致があればその情報を付けます。注文のある顧客だけ見たいのか、注文のない顧客も含めたいのかによって、選ぶ方式が変わります。

目的結合の種類一致しない行
注文がある顧客と注文を表示内部結合 INNER JOIN結果から外れる
顧客全件に注文を付けて表示顧客を残す外部結合注文側の項目がNullになる
注文全件に顧客情報を付ける注文を残す外部結合顧客側の項目がNullになる
両方に一致する行だけ残す内部結合と顧客全件を残す外部結合を比較する図

リレーションシップとの違い

データベースのリレーションシップは、テーブル同士の関係を定義する設定です。参照整合性を設定すると、存在しない親IDを子テーブルに登録するような不整合を防ぐ役割も持ちます。一方、クエリ内の結合は、そのクエリの結果をどう組み立てるかを決めるものです。

リレーションシップがあるとクエリに結合線が自動表示される場合がありますが、クエリで線を引いただけでデータベース全体の整合性が保証されるわけではありません。また、同名の項目が自動で結ばれても正しいとは限らないため、そのIDが両表で同じ対象を表しているか確認します。


共通キーとサンプルテーブルを準備する

結合の成否は、共通キーの意味とデータ型に左右されます。顧客名は同名や表記ゆれがあるため、管理用の顧客IDを使うのが基本です。別システムで独立して採番されたIDなら、同じ数字でも同じ顧客を表すとは限りません。対応表などが必要になる場合があります。

2つの表と期待結果を用意する

ここではT_顧客とT_注文を使います。顧客IDはT_顧客側で数値型の長整数・主キー、T_注文側でも長整数とします。実システムで親がオートナンバー型の場合は、通常の長整数オートナンバーに対応する子側の項目を長整数にそろえます。

T_顧客の顧客ID顧客名
10青空商店
20木立工業
30港事務所
T_注文の注文ID顧客ID注文日注文金額
101102026/10/011000
102102026/10/032000
103202026/09/203000
顧客3件と注文3件を顧客IDで結ぶサンプル構成

このサンプルでは内部結合は3行、顧客を全件残す外部結合は4行になります。顧客10に注文が2件あるので、顧客10の行が2回現れます。顧客が3件だから結果も必ず3件になるという考え方は誤りです。どの単位で1行になるのかを、先に言葉で定義してください。

型と値の品質を確認する

数値の10と、文字列の”010″を同じとみなすかは、業務上のルール次第です。型を変換すればよいと即断せず、先頭ゼロの意味やコード体系を確認します。Null、余分な空白、旧コードと新コードの混在も、不一致の原因になります。元データを無断で置換せず、対応関係を明確にします。


デザインビューで結合クエリを作成する

クエリデザインで2表を追加し、共通キーをドラッグして結合線を引きます。その後、残したい側に合わせて結合プロパティを選びます。表の左右の配置だけで判断せず、ダイアログに書かれたテーブル名と「全レコード」という説明を読んで選択してください。

1. [作成]→[クエリデザイン]からT_顧客とT_注文を追加します。

2. T_顧客の顧客IDをT_注文の顧客IDへドラッグします。

3. 結合線をダブルクリックして、結合プロパティを開きます。

4. まず両方で一致するレコードだけを含む設定を選びます。

5. 顧客ID、顧客名、注文ID、注文日、注文金額をグリッドへ追加します。

6. データシートビューで3行になることと、顧客10が2行あることを確認します。

2表追加、ID接続、結合種類選択、表示列と結果確認の手順

内部結合のSQL例

次のSQLは、顧客IDが一致する注文と顧客を結びます。CとOはテーブルを短く呼ぶ別名です。同じ顧客IDという項目名が両表にあるため、C.[顧客ID]のようにどちらの表かを指定します。ORDER BYは表示順を決めるものであり、結合の成立条件ではありません。

SELECT C.[顧客ID], C.[顧客名],
 O.[注文ID], O.[注文日], O.[注文金額]
FROM [T_顧客] AS C INNER JOIN [T_注文] AS O
 ON C.[顧客ID] = O.[顧客ID]
ORDER BY C.[顧客ID], O.[注文ID];

結合線を削除してしまうと、条件のない2表の組み合わせが作られる場合があります。
サンプルでは顧客3行×注文3行で9行です。結果が急に増えたときは、DISTINCTで隠す前に結合線とONの条件が正しいか確認してください。


外部結合で消える行とNullを確認する

顧客を全件残すには、結合プロパティでT_顧客の全レコードを含む設定にします。SQLならT_顧客を左側に置いたLEFT JOINです。注文のない顧客30も残り、注文ID、注文日、注文金額はNullになります。Nullはゼロや空文字そのものではありません。

SELECT C.[顧客ID], C.[顧客名], O.[注文ID]
FROM [T_顧客] AS C LEFT JOIN [T_注文] AS O
 ON C.[顧客ID] = O.[顧客ID]
ORDER BY C.[顧客ID], O.[注文ID];

顧客ID顧客名注文ID
10青空商店101
10青空商店102
20木立工業103
30港事務所Null
注文のない顧客は残し、注文IDをNullで表示する左結合の結果

不一致の判定には相手側の主キーを使う

注文がない顧客だけを知りたいときは、上のLEFT JOINにWHERE O.[注文ID] Is Nullを加えます。判定対象には、実在する注文ではNullにならない主キーを使います。注文備考など、注文があっても空欄になり得る項目で判定すると、存在する注文を不一致と誤認する原因になります。

相手側の条件をWHEREに書くと行が消える

LEFT JOINの後にWHERE O.[注文日]>=DateSerial(2026,10,1)を置くと、注文日がNullの行は条件を満たさず消えます。「外部結合にしたから顧客は必ず全部残る」とは限りません。抽出条件は結合結果に対して作用するため、結合の種類と条件の位置を合わせて考えます。

10月の注文だけ付けながら顧客全件を残すなら、先に10月の注文を抽出するQ_10月注文を保存し、そのクエリと顧客をLEFT JOINします。9月にしか注文のない顧客20も残ります。単純に「10月または注文IDがNull」とすると、この顧客20を取りこぼす点に注意してください。

SELECT [注文ID], [顧客ID], [注文日], [注文金額]
FROM [T_注文]
WHERE [注文日] >= DateSerial(2026,10,1)
  AND [注文日] < DateSerial(2026,11,1);
SELECT C.[顧客ID], C.[顧客名], O.[注文ID]
FROM [T_顧客] AS C LEFT JOIN [Q_10月注文] AS O
 ON C.[顧客ID] = O.[顧客ID]
ORDER BY C.[顧客ID], O.[注文ID];

注文を先に抽出してから顧客全件と結ぶ方法を示した図

クエリの結合・集計不整合を整理したい方へ

検証用データで手順を確かめても解決しない場合や、複数の画面・テーブル・利用者への影響を整理する必要がある場合は、Accessの教科書へご相談ください。現在の構成、起きている症状、期待する結果をまとめると、確認すべき範囲を伝えやすくなります。


件数増加と二重集計を防ぐ

結合後の行数は、キーごとの組み合わせ数で決まります。左側に同じキーが2行、右側に3行あれば、そのキーだけで2×3の6行になります。顧客名や日付のような重複する値を結合キーにすると、予想外の増加が起こりやすくなります。

一対多が正しいのかを確認する

顧客1件に注文が複数ある関係は、通常の一対多です。注文一覧を作るなら行が増えるのは正しい結果です。一方、顧客ごとの注文合計を1行で表示するなら、注文を顧客IDで先に集計してから顧客へ結合します。同じ処理を、欲しい結果の単位によって使い分けます。

同じキーが左2行と右3行にあると組み合わせが6行になる図

親の金額を明細の件数だけ足さない

注文と注文明細を結合すると、注文側の合計金額が明細の数だけ繰り返されます。注文金額3000円の注文に明細が3行あると、結合後の注文金額を合計して9000円にしてしまう可能性があります。注文金額は注文単位で集計し、明細金額は明細単位で集計するなど、粒度をそろえてください。

注文金額が明細ごとに繰り返されるため先に粒度をそろえる例

DISTINCTは、結果の列の組み合わせが同じ行を取り除く機能です。誤った結合キーや粒度を正しくする機能ではありません。金額の重複だけを消すと、偶然同額だった別の注文までまとめてしまうおそれがあります。件数や合計値が合わないときは、どのIDが何行に展開されたかを調べます。

重複しているキーを調べる

次は取り込んだ顧客表の顧客IDが重複していないか調べる例です。主キーを設定した正規の表なら重複を防げますが、CSV取込用の表などでは設定されていない場合があります。重複が業務上の履歴なのか、誤登録なのかを確認してから対応してください。

SELECT [顧客ID], Count(*) AS [件数]
FROM [T_顧客取込]
GROUP BY [顧客ID]
HAVING Count(*) > 1;


複合キーと運用前の確認

1項目だけでは同じ行を特定できない場合は、複数項目を組み合わせて結合します。例えば注文明細を照合するときは、注文IDと明細番号の両方が必要です。注文IDだけで結ぶと、同じ注文にある明細同士が総当たりで対応し、件数や金額が増える原因になります。

SELECT A.[注文ID], A.[明細番号], B.[商品コード]
FROM [T_明細A] AS A INNER JOIN [T_明細B] AS B
 ON A.[注文ID] = B.[注文ID]
 AND A.[明細番号] = B.[明細番号];

3表以上を結ぶ場合も、一度に複雑なクエリを完成させようとせず、まず2表で件数を確認します。外部結合と内部結合の組み合わせでは、結合順やAccessの構文上の制約が問題になることがあります。途中結果を保存クエリに分けると、どの段階で行が消えたか追いやすくなります。

最低限の検算を行う

1. 結合するIDの意味、型、重複、Nullを調べます。

2. 元の行数と、結合後の行数を記録します。

3. 一致する行、片側だけの行、同じキーが複数ある行を試します。

4. 注文金額などの合計を、結合前の正しい単位の合計と照合します。

5. 抽出条件を付けても、残すべき行が残るか確認します。

キー重複、Null、件数、金額、複合キーを確認する一覧

結合結果を編集できるかは、キーやクエリの構造、データソースによって変わります。表示できるから安全に更新できるとは判断せず、集計・DISTINCT・複数表結合を使う画面では、入力用と表示用を分ける設計も検討してください。まず正しい結果を作り、その後に更新範囲を決めます。


よくある質問

関係はありますが同じではありません。リレーションシップはテーブル間の関係をデータベースに定義し、参照整合性などを設定するものです。クエリの結合は、その結果にどの行を含めるかを決めます。既存の関係から結合線が自動表示される場合もありますが、線を引いただけで新しいデータの整合性を保証するわけではありません。逆に、リレーションを作っていなくてもクエリ内で結合できます。目的と設定する場所を区別して扱ってください。

両方に一致する行だけ欲しいなら内部結合、左側の表を全件残したいなら左外部結合を使います。例えば注文のある顧客だけを見る一覧は内部結合、注文のない顧客も含む一覧は顧客を左側にした外部結合です。ただし、右側の項目に後から抽出条件を付けると、Nullの行が消える場合があります。結合種類だけで判断せず、どちらの表を残すか、条件をどの段階で適用するか、期待する件数はいくつかをセットで確認します。

同じキーに複数の行が対応すると、その組み合わせごとに結果が作られるためです。顧客1件に注文が3件あれば顧客情報は3回現れます。また、左側に2件、右側に3件の同じキーがあると6件になります。注文一覧なら正しい場合もありますが、顧客単位の一覧なら事前集計などが必要です。DISTINCTで見た目を減らす前に、どのキーが重複しているか調べてください。注文IDだけでは足りず、明細番号も結合条件に必要なケースがあります。

相手側の項目に付けたWHERE条件が、Nullの行を除外している可能性があります。例えば顧客を残すLEFT JOINでも、注文日を10月に限定すると、注文のない顧客や9月にしか注文のない顧客が消えます。顧客を全件残しつつ10月注文だけ付けたいなら、先に注文を10月に絞った保存クエリを作り、それと顧客を結合してください。単純にNullの条件をORで加えるだけでは、他の月に注文がある顧客を残せない場合があります。

フィールド名が違っていても、同じ対象を表す値でデータ型に互換性があれば結合できます。例えば顧客IDと取引先番号でも、同じコード体系なら対応付けられます。反対に、両方がIDという名前でも、独立して採番されていれば一致させてはいけません。まず番号の発行元と意味を確認してください。文字列の0010と数値の10など表記が違う場合も、安易に型変換して先頭ゼロを落とさず、業務ルールに合う対応表や変換処理を設計します。

できます。ただし、2表ずつ結果を確かめながら追加する方が原因を追いやすくなります。顧客、注文、注文明細の順で結ぶ場合は、各段階で1行が何を表すか、件数が何倍になるかを確認してください。内部結合と外部結合を混在させると、結合順序の曖昧さや構文の制約に直面する場合があります。その場合は途中結果を保存クエリに分け、次の表と結合する方法を検討します。結合線を増やす前に、必要な表だけかどうかも見直しましょう。

常に編集できるわけではありません。集計、DISTINCT、結合の構造、主キーの有無、リンク先の権限などによって更新不可になる場合があります。表示結果の1行が、保存先のどの行に対応するかが明確であることが重要です。まず検証用コピーで対象項目だけを変更し、意図した行に保存されるか確かめてください。集計や照会を目的とする複雑なクエリでは、入力用フォームを別に用意し、表示と更新を分ける方が管理しやすい場合があります。

Accessの通常のクエリでは、FULL OUTER JOINをそのまま指定する方法は使えません。左側を全件残す結果に、右側だけにある行を追加するようなUNIONクエリの構成を検討します。両側の外部結合をそのままUNION ALLすると、一致した組み合わせを二重に含む可能性があるため注意してください。列数と型をそろえ、右側だけの抽出条件に相手の主キーのIs Nullを使います。差分確認が目的なら、左右別々の不一致クエリの方が分かりやすい場合もあります。

Accessの教科書へのご相談

クエリの結合・集計不整合を整理したい方へ

検証用データで手順を確かめても解決しない場合や、複数の画面・テーブル・利用者への影響を整理する必要がある場合は、Accessの教科書へご相談ください。現在の構成、起きている症状、期待する結果をまとめると、確認すべき範囲を伝えやすくなります。

関連記事

Accessで2つのテーブルの一致レコードを抽出

Accessで2つのテーブルを比較

Accessクエリでグループ化して集計


参考情報

Microsoft Support テーブルとクエリの結合
https://support.microsoft.com/en-us/access/join-tables-and-queries

Microsoft Learn INNER JOIN
https://learn.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/inner-join-operation-microsoft-access-sql

Microsoft Learn LEFT JOINとRIGHT JOIN
https://learn.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/left-join-right-join-operations-microsoft-access-sql

TOP