論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
外部結合
Outer Join
データ処理

🔖 キーワード索引

#LEFT JOIN#FULL JOIN#欠損#merge#結合#NULL

outer join」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「outer join」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。

outer join統計分析SSDSE-B-2026前提条件適用範囲落とし穴関連手法Python 実装検証方法

これらのキーワードは「outer join の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。

💡 30秒で分かる結論

🍰 まずはやさしく

足りない部分を埋めてつなげる方法です。

データの抜けをなくすために使います。

名簿とアンケート結果を合わせる時に便利です。

外部結合の結論をさっと確認しましょう。

外部結合:片側または両側のキーをすべて残す結合

📍 文脈ボックス

🍰 まずはやさしく

データ処理の重要なテクニックです。

分析でデータを正しく扱うために使います。

スマホのアプリなどでデータをまとめる時に役立ちます。

この用語を学ぶための全体の流れを説明します。

この用語は データ処理 カテゴリに属します。 関連する別称・略号:(なし)

論文・実務レポートで 外部結合 が登場したら、 まず本ページの「30秒で分かる結論」と「直感で掴む」を読めば、 その文脈で何を言っているか把握できます。

本ページでは「outer join」を扱う。 統計データ分析コンペティション (2026) の教材で、 SSDSE-B-2026 (47 都道府県 × 複数年 × 100 超列) の実データを使った再現可能な学習を目指す。

「outer join」は統計・データサイエンスの体系における重要概念のひとつ。 本ページは「定義・直感・数式・実装・落とし穴・関連手法」の 6 視点で構成され、 各視点は独立して読めるが順序通り読むと体系的な理解が得られる。

🎨 直感で掴む

🍰 まずはやさしく

パズルのピースを無理やり合わせるイメージです。

どちらか一方にしかない情報を残すために使います。

部活の名簿と出席簿を比べる時に便利です。

図や例を使って直感的に仕組みを理解しましょう。

SSDSE-B-2026 (47 都道府県 × 経済社会指標) と、 別ファイルの SSDSE-D-2023 (一部都道府県のみの観光統計) を 都道府県 列で結合したいとする。 B には 47 件全て、 D には 30 件しかない。 結合の仕方でテーブルの形が劇的に変わる:
内部結合 (inner join):両方に存在する 30 件のみ残す。
左外部結合 (left outer join):B の 47 件全部残し、 D の値は無ければ NaN
右外部結合 (right outer join):D の 30 件全部残し、 B の値は無ければ NaN
完全外部結合 (full outer join):B にも D にも在る全ての都道府県 (この例なら 47 件) を残し、 片側欠損は NaN

つまり 外部結合 (outer join)とは「片方にしか無いキーも保持する」結合のこと。 内部結合と違って 結合キーの不一致による情報損失が無いのが最大の特徴で、 欠損行を後で「分析対象から除く/追加調査する」と判断できるのが実務的価値。 SQL では LEFT/RIGHT/FULL OUTER JOIN、 pandas では df.merge(other, how='left'|'right'|'outer')

初学者がよくミスするのは「外部結合したのに結果が内部結合と同じ件数になる」現象。 これは マージキーの型不一致str vs int) や、 表記揺れ (北海道 vs 北海道 [全角・半角]) で照合が失敗しているサイン。 後述の落とし穴で詳説する。

📐 定義・数式

🍰 まずはやさしく

数学的なルールで決まったつなぎ方です。

正確にデータを結合させるために使います。

買い物リストと在庫表を厳密に合わせる時に役立ちます。

数式を使って外部結合の定義を詳しく学びましょう。

【外部結合の論理】
$$ A \,\bowtie_{\text{LEFT}}\, B = (A \,\bowtie\, B) \cup \{(a, \text{NULL}) \mid a \in A,\, \nexists b \in B\} $$

LEFT OUTER JOIN は、 INNER JOIN の結果に「左にしか存在しない行を NULL 埋めで追加」したもの。 RIGHT は逆、 FULL は両方追加。

🔬 数式を言葉で読み解く

数式に出てくる記号の意味を 1 つずつ確認しましょう。

INNER JOIN
両方に存在するキーのみ。 マッチしないと消える。
LEFT OUTER
左テーブルを全部残し、 右の不足は NULL。
RIGHT OUTER
右テーブルを全部残す。
FULL OUTER
両方とも全部残す。

🔬 数式を言葉で読み解く(深掘り)

先の「記号を読み解く」を、 外部結合 の固有事情に即して 500 字以上で詳説する。 ここを読めば、 数式 1 行の裏にある設計判断と歴史的経緯が見えるはずだ。

LEFT (左): 左表 $L$ の全行を残し、 右表 $R$ にマッチが無ければ右側列を NULL/NaN。 件数は $|L|$ 以上 (1 対多なら膨張)。 RIGHT (右): 鏡像。 右表 $R$ の全行を残す。 SQL 標準だが、 慣習的に LEFT JOIN を使うほうが読みやすく推奨される。 FULL (完全外部): 両側の全行を残し、 片側欠損は NULL/NaN。 件数は $|L \cup R|$。 INNER: マッチした行のみ。 件数は $|L \cap R|$ で、 outer の特殊形 (NaN 行を捨てる)。 JOIN キーは 1 列でも複数列でもよく、 pandas では on=['都道府県', '年度'] のように複合キーを指定できる。 $L \bowtie_K R$ という関係代数の表記は、 集合論的には「直積 + 選択 + 射影」の合成で、 外部結合はこれに「片側に対応する NULL 行を補う」操作を追加したもの。 つまり外部結合 = 内部結合 + マッチしなかった側を NULL で補完。 この拡張により情報損失なく集合演算を行える設計で、 リレーショナル代数を「現実のデータ統合」に橋渡しする中核演算。

📌 数式は 暗記対象ではなく検算ツール。 「結果が変だ」と感じたとき、 「この記号は本来こういう意味だから、 ここの値はおかしい」と 逆引きできる状態が、 中級者と上級者の差を生む。

🧪 SSDSE-B-2026 ハンズオン

本サイトの標準データ SSDSE-B-2026(47 都道府県 × 約 100 列、 独立行政法人統計センター提供) を使い、 外部結合 の概念を 実コードで体感する。 取得経路は data/raw/SSDSE-B-2026.csv(リポジトリ同梱)。

SSDSE-B-2026 (経済社会指標) と SSDSE-D-2023 (家計消費) を都道府県名で完全外部結合する。 D には鳥取・島根が含まれない仮想シナリオで、 結果テーブルの「鳥取・島根」行で D 由来の列が NaN になることを確認する。 4 ステップ:(1) 両 CSV 読込 → (2) キー前処理 → (3) how='outer' でマージ → (4) 欠損確認・indicator=True で由来追跡。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 Prefecture(都道府県) 北海道 北海道 東京都 東京都 沖縄県 沖縄県 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# SSDSE-B (経済社会) と SSDSE-D (家計消費) を都道府県名で full outer join する
import pandas as pd
b = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=1, encoding='cp932')
d = pd.read_csv('data/raw/SSDSE-D-2023.csv', skiprows=1, encoding='cp932')
# キー正規化(前後空白・全半角)
b['都道府県'] = b['都道府県'].str.strip()
d['都道府県'] = d['都道府県'].str.strip()
# full outer join + 由来追跡
merged = b.merge(d, on='都道府県', how='outer', indicator=True, suffixes=('_b', '_d'))
print('shape =', merged.shape)
print(merged['_merge'].value_counts())  # left_only / both / right_only
# どの都道府県が片側だけだったか
print('B にのみ:', merged.loc[merged['_merge']=='left_only', '都道府県'].tolist())
print('D にのみ:', merged.loc[merged['_merge']=='right_only', '都道府県'].tolist())
# 完全マッチ件数と NaN を抱える件数の比較
print('NaN を含む行 =', merged.isna().any(axis=1).sum())
📤 実行例(実測) shape = (1695, 236) _merge both 1692 right_only 3 left_only 0 Name: count, dtype: int64 B にのみ: [] D にのみ: ['全国', '全国', '全国'] NaN を含む行 = 3

📌 動かないときは: (1) data/raw/SSDSE-B-2026.csv がリポジトリに存在するか、 (2) skiprows=1 でヘッダーが正しく読めているか、 (3) 列名が SSDSE 公式の最新版と一致しているかを df.columns.tolist() で確認。

🔬 外部結合と関連トピックの統合理解

外部結合を「単独の操作」 として理解するのではなく、 データ分析パイプラインの中での位置づけを意識すると、 その価値が見えてくる。 典型的な分析フローは「データ取得 → 前処理 → 結合 → 集計 → 可視化 → 解釈」 で、 結合はパイプラインの中間に位置する。 結合の前にはキーの正規化・型変換・欠損処理が必要、 結合の後には集計や可視化が続く。 結合だけ最適化しても、 前後の処理が雑だと結果は信頼できない。 SSDSE-B-2026 のような教育用データセットを使って、 結合前後の処理を含めた一連のフローを体得することが学習の本質。

📊 分析パイプラインでの外部結合の位置づけ

段階処理外部結合との関連SSDSE-B-2026 での例
1. データ取得CSV・API・DB からロード取得元が複数なら結合が必要SSDSE と e-Stat を別々にダウンロード
2. 前処理正規化・型変換・欠損処理結合キーの統一が必須都道府県コードの文字列化、 ゼロパディング
3. 結合LEFT/RIGHT/FULL OUTER本トピック中心マスタ + 集計テーブルを結合
4. 集計GROUP BY、 pivot_table結合後の NULL に注意地方別集計、 年度別集計
5. 可視化matplotlib, seaborn結合結果の品質確認都道府県別の棒グラフ・地図
6. 解釈統計的検定・モデル化結合の欠損が結果に影響地域差の有意性検定
7. 報告レポート・ダッシュボード結合手法の明示が必要方法論セクションに結合戦略を記述

→ 結合はパイプラインの中間に位置するが、 前後の処理に影響を与える critical な操作。 雑な結合は、 雑な集計・可視化・解釈を生む。 「結合のためだけに前処理を念入りにする」 という意識が、 データ品質を支える。 SSDSE-B-2026 のような小データでも、 こうしたパイプライン意識を持って取り組むことが、 実務での大規模データへの拡張を可能にする。

📏 結合品質の定量指標

指標定義計算式SSDSE-B-2026 での目安
マッチ率左テーブルの行のうち右テーブルとマッチした割合matched / left_rows100% が理想 (47/47)
NULL 率結合後の値列で NULL の割合nulls / total_rows0% が理想
重複率1:1 結合のはずが N:M で増えた割合(joined - left) / left0% が理想 (爆発検知)
カバレッジ右テーブルの行が結合に使われた割合used_right / right_rows100% が理想
欠損キー数結合キーが NULL の行数count where key IS NULL0 が理想
型不一致数左右で結合キーの型が異なる行0 が理想
前後比較結合前後の集計値の整合性SUM_before == SUM_afterNULL 補正後の総計が一致

これらの品質指標を結合の都度確認することで、 「気づかないうちにデータが消失」「気づかないうちに行数爆発」 等の事故を防げる。 マッチ率 95% を下回ったら結合キーを疑う、 NULL 率が想定外に高ければデータ欠損を調査する、 重複率が 0% でなければ結合キーの一意性を再確認する、 という判断基準を持つことが、 データエンジニアの基礎力。 SSDSE-B-2026 のような小データで原理を学び、 業務で大規模データに適用する際に、 これらの指標を必ずチェックする習慣が、 品質保証の根幹となる。

🧪 SSDSE-B-2026 を題材にした外部結合のステップバイステップ演習

SSDSE-B-2026 (47 都道府県データ) を題材に、 外部結合の演習を順に進める。 ステップ 1: SSDSE-B-2026 から「都道府県コード, 都道府県名, 総人口」 の 3 列を抽出して左テーブルとする。 ステップ 2: 別途、 e-Stat 等から「都道府県コード, 65 歳以上人口」 を取得して右テーブルとする (一部県のみのデータと仮定)。 ステップ 3: pd.merge(left, right, on='code', how='left', indicator=True) で LEFT OUTER 結合し、 indicator 列で結合状況を記録。 ステップ 4: df['_merge'].value_counts() で「左のみ」「両方」 の行数を確認。 ステップ 5: df['rate_65_plus'] = df['65歳以上人口'] / df['総人口'] で高齢化率を計算 (NULL は無視される)。 ステップ 6: df.dropna(subset=['rate_65_plus']) で欠損行を除いて分析、 または df['rate_65_plus'].fillna(df['rate_65_plus'].mean()) で平均値補完。 ステップ 7: 結果を都道府県別の棒グラフで可視化。 こうした 7 ステップの演習が、 外部結合と pandas の総合理解を体感的に身につけさせる。

この演習の発展として、 (1) FULL OUTER で双方の欠損を確認、 (2) INNER JOIN との結果比較、 (3) 結合品質を indicator 列の集計で定量化、 (4) NULL の集計時の影響 (SUM/AVG が NULL を無視する性質) を体感、 (5) COALESCE 相当の fillna で NULL を 0 に置換した場合の結果との比較、 等を試す。 各ステップで len(df)df.isnull().sum()df.head() を確認する習慣を身につけることで、 結合のバグを早期発見する基礎力が育つ。 SSDSE のような信頼できる小データだからこそ、 こうした地道な確認作業の重要性を体感できる。 業務で大規模・複雑なデータを扱う際にも、 この基礎が品質保証の根幹となる。 この演習を通じて、 学生諸氏は「結合の本質」 を頭で理解するだけでなく、 「自分の手で動かして体感する」 ことができる。 こうした実践的経験が、 将来の業務・研究で出会う多様なデータ結合の場面で生かされる、 一生ものの基礎技能となる。 SSDSE-B-2026 という公的データを使った地道な演習の積み重ねが、 データサイエンティストとしての成長の核心であり、 統計データ分析コンペティションへの参加準備の最良の方法でもある。 学生諸氏には、 本ページの内容を起点に、 実際にコードを書き、 結果を観察し、 仮説を検証する反復を通じて、 外部結合の本質を体得してほしい。 そうした地道な学びこそが、 将来のあらゆるデータ分析の場面で生きる力となる。 SSDSE のような公的データを使った演習と、 業務での大規模データへの応用を往復することで、 外部結合の理論と実践が一体化し、 真に「使える技能」 として定着していく。

🧮 実値で計算してみる

都道府県マスターと観光統計表を結合する例。

STEP 1 マスター読み込み
47 都道府県のテーブル A。
STEP 2 明細読み込み
30 県分の観光客数テーブル B。
STEP 3 LEFT JOIN
pd.merge(A, B, how='left', on='都道府県')
STEP 4 NaN 確認
結合後、 17 県の観光客数列が NaN になる。

🧮 数式に値を入れて手で計算する: OUTER JOIN 結果行数

合成 2 テーブルで FULL OUTER JOIN の結果行数を計算する。

Step 1: テーブル

A: {1, 2, 3, 4} (4 行) B: {3, 4, 5, 6, 7} (5 行) INTERSECT: {3, 4} (2 行)

Step 2: 各種 JOIN 行数

INNER: 2 (一致) LEFT: 4 (A 全件) RIGHT: 5 (B 全件) FULL OUTER: 4 + 5 - 2 = 7

🐍 Python で再現

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
A = {1, 2, 3, 4}
B = {3, 4, 5, 6, 7}
inner = len(A & B)
left = len(A)
right = len(B)
full = len(A | B)
print(f"INNER: {inner}")
print(f"LEFT: {left}")
print(f"RIGHT: {right}")
print(f"FULL OUTER: {full}")

📤 実行結果

INNER: 2 LEFT: 4 RIGHT: 5 FULL OUTER: 7

💬 手計算 (Step 2) と Python 出力が完全一致。

🐍 Python 実装

最小実装の例。 SSDSE のような実データに対して、 まずはコピペで動かしてみるのが理解の早道です。

1
2
3
4
5
import pandas as pd
master = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=1, encoding='cp932')
detail = pd.read_csv('data/raw/tourism.csv')
merged = pd.merge(master, detail, how='left', on='都道府県')
print(merged['観光客数'].isna().sum(), 'rows missing')

🐍 Python 実装(応用編)

先の Python 実装は最小例だった。 ここでは 外部結合 の本格的な実務シナリオに即した、 もう一段難易度を上げたコードを示す。 そのままコピペで動くよう、 SSDSE 系の実データパスを直書きで残してある。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 SSDSE-B-2026(年度) Prefecture(都道府県) A1101(総人口) 北海道 2,023 北海道 5,092,000 東京都 2,023 東京都 14,086,000 沖縄県 2,023 沖縄県 1,468,000 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# ── この抜粋で使うデータを用意します(英字の項目コードで読み込み)──
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=0)
df = df[df['Code'].astype(str).str.match(r'^R\d{5}$', na=False)].copy()
for _c in df.columns[3:]:
    df[_c] = pd.to_numeric(df[_c], errors='coerce')
df = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()]

# ── この抜粋で使う 3 つの表を用意します ──
import pandas as pd

b = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=1, encoding='cp932')
b = b[b['年度'] == 2023][['都道府県', '総人口']]
d = pd.read_csv('data/raw/SSDSE-D-2023.csv', skiprows=1, encoding='cp932')
d = d[d['男女の別'] == '0_総数'][['都道府県', '推定人口(10歳以上)']]
e = pd.read_csv('data/raw/SSDSE-E-2026.csv', skiprows=2, encoding='cp932')
e = e[['都道府県', '一般世帯数']]
for _t in (b, d, e):
    _t['都道府県'] = _t['都道府県'].astype(str).str.strip()

# SSDSE-B, SSDSE-D, SSDSE-E の 3 つを都道府県名で full outer join し
# 「どの表に居ない都道府県があるか」を indicator で追跡する例
import pandas as pd

# それぞれ独立に full outer join
step1 = b.merge(d, on='都道府県', how='outer', indicator='in_BD')
step2 = step1.merge(e, on='都道府県', how='outer', indicator='in_BDE')
print('shape =', step2.shape)
print(step2['in_BD'].value_counts())
print(step2['in_BDE'].value_counts())

# 全表にあるのは? 1 表だけのは?
in_all = step2.query('in_BD == "both" and in_BDE == "both"')['都道府県'].tolist()
print('全表に存在:', len(in_all), '件:', in_all[:5])
only_b = step2.query('in_BD == "left_only"')['都道府県'].tolist()
print('B のみ:', only_b[:5])
📤 実行例(実測) shape = (48, 6) in_BD both 47 right_only 1 left_only 0 Name: count, dtype: int64 in_BDE both 48 left_only 0 right_only 0 Name: count, dtype: int64 全表に存在: 47 件: ['三重県', '京都府', '佐賀県', '兵庫県', '北海道'] B のみ: []

📌 このコードのポイント: (1) 引数化せず実データパスを直書きで読みやすさ優先、 (2) 集約・結合・型最適化など 外部結合 関連の典型処理を一気通貫で示す、 (3) print() で各ステップの結果を確認できる。

🧭 用語クロスリンク集

外部結合 と関わりの深い用語を、 一画面で巡回できるよう チップ形式で並べた。 「これも知っておきたい」と思った瞬間にクリックして、 元のページに戻ってくる ── ジャストインタイム学習の理想的な使い方。

🔗 内部結合 🔗 テーブル 🔗 DataFrame 🔗 主キー 🔗 外部キー 🔗 SQL 🔗 データベース 🔗 CSV 🔗 JSON 🔗 正規表現 🔗 ピボットテーブル 🔗 ログデータ 🔗 用語索引

📌 これらはすべて html/glossary/ 配下の実在ページにリンクしているので、 リンク切れの心配はない。

🗂 用語の階層・派生・対立関係

外部結合 を中心に、 上位概念・並列概念・派生概念・対立概念の 4 区分で整理。 学術論文を読むときの「この用語はこの分野のどこに位置するか」を直感的に把握できる。

関係該当用語関係性の説明
上位概念データエンジニアリング 一般本ページの用語が属する分野全体
並列概念同カテゴリの兄弟用語「🔗 関連用語」セクション参照
派生概念発展手法・拡張版「🌐 関連手法・派生」セクション参照
対立概念「🔍 近接概念との比較(深掘り)」の右列混同しがちな対比対象
前提知識「📜 歴史的背景」で示した文脈本用語を理解する前に知っておくべき内容

⚠️ よくある落とし穴

外部結合は「片方にしか存在しない行」を残す結合で、 INNER JOIN との取り違えと NaN 処理ミスが事故の二大原因。 SSDSE で「都道府県名」と「県名」を結合する際、 表記揺れ (東京 / 東京都) で NaN 量産 → 集計結果が崩壊するパターンが典型。 結合前に必ず両側の unique key を可視化したい。

❌ 結合キーの表記揺れ
SSDSE-B-2026 では「東京都」、 観光統計では「東京」、 英文資料では「Tokyo」と表記が違う。 outer join で何も前処理しないと NaN が量産され、 実際にマッチする行はわずか。 結合前に set(df1.key) - set(df2.key) で差分を確認し、 名寄せ辞書(マッピング表)で統一する。
❌ 行数増殖
結合キーがユニークでない場合(同じ都道府県コードが複数行ある等)、 outer join 結果は左 m 行 × 右 n 行に増殖する。 47 県のはずが数百行になることも。 結合前に df.duplicated(subset='key') で重複を確認し、 必要なら集約(groupby().agg())してから結合する。
❌ NaN を 0 で埋める誤り
outer join で発生した NaN を fillna(0) で埋めると、 「観光客 0 人だった県」と「データ取得失敗の県」が同じ 0 として扱われ、 平均値・分散・回帰係数が歪む。 NaN の発生源(左のみ・右のみ)を indicator=True で残し、 「データ欠損」と「真の 0」を区別する。
❌ FULL OUTER の濫用
FULL OUTER は「両側にしかないキー」を全て残すため、 共通キーが少ない 2 表(東京 23 区データ × 全国都道府県データ)では片側 NaN が大量発生する。 分析目的に応じて inner / left / right を選び、 「両側存在を残す必要性」を本当に検討してから FULL OUTER を選択する。

⚠️ もっと深い落とし穴

上のセクションの 4 つに加えて、 外部結合 固有の実務でハマる典型をさらに 4 つ。 経験 5 年以下のエンジニア・研究者はほぼ全員、 ここのいずれかで 1 度は事故を起こしている。

❌ セミコロンと NaN 混在
indicator=True で出力される _merge 列の値 (left_only 等) はカテゴリ型。 後で isna() と組合せると挙動が直感的でないことがある。
❌ ソートが崩れる
merge(..., sort=False) がデフォルト。 結合後の行順は保証されない。 必要なら sort_values()
❌ カラム名の自動 suffix
両表に同名の非結合キー列があると col_x, col_y が自動付与。 suffixes=('_b', '_d') で意味のある接尾辞に。
❌ 巨大表で OOM
1 億 × 1 億の full outer join は 10 兆セル級になり得る。 結合前に where で絞り、 hash join戦略を意識。

🗺 概念マップ:外部結合 の知識ネットワーク

本サイト全体の 概念マップ の中で、 外部結合 がどの位置にあるかをテキストツリーで表現する。 視覚的なグラフは 概念マップページ を参照。

[ データエンジニアリング ]
  ├─ 外部結合 (本ページ)
  ├─ 関連手法・派生 → 「🌐 関連手法・派生」セクション
  ├─ 前提概念 → 「🔬 数式を言葉で読み解く」セクション
  └─ 派生領域 → 「🎓 深掘り(さらに)」シナリオ A/B/C
  

📌 全用語の俯瞰には 概念マップ を、 全用語一覧には 用語集トップ を参照してください。

🎯 最終まとめ:このページで学んだこと

  1. 30 秒結論で「外部結合 とは何か」を 1 文で言える
  2. 直感セクションで SSDSE-B-2026 を題材に具体例を掴んだ
  3. 数式 + 言葉で記号の意味を翻訳できる
  4. Python 実装を最小例 + 応用例の 2 段で試せた
  5. 落とし穴 8 個を知り、 自分の作業で予防策が打てる
  6. 3 シナリオ × 3 誤解 × 5 意思決定で、 「いつ使うか/使わないか」を判断できる
  7. 近接概念との比較で、 別手法との違いを言葉で説明できる
  8. 歴史・派生・体系的解説で、 上級者として「なぜこの設計か」を語れる

📌 本ページは ジャストインタイム型データサイエンス教育教材の一部。 一度通読する必要はなく、 必要なときに必要な節だけ読んで戻ってくる使い方を想定している。 「外部結合」の概念に詰まったら、 何度でもこのページに戻ってきてほしい。

🔢 数値例による手計算ウォークスルー

外部結合 を「コード任せ」にせず、 一度は手計算してみることで理解が定着する。 ここでは最小サイズのデータで、 値の動きを 1 ステップずつ追う。

数値例:47 vs 30 件の都道府県表を full outer join

SSDSE-B-2026 (47 都道府県) と仮想 D 表 (30 都道府県のみ、 鳥取・島根・福井・山梨・佐賀・宮崎・大分・愛媛・徳島・高知・福島・岩手・秋田・新潟・富山・石川・岐阜・三重 を欠く) を都道府県名で結合した結果を 4 方式で比較。

結合方式結果行数NaN 行数用途
INNER JOIN300両方在る対象だけ分析
LEFT OUTER JOIN (B 左)4717 (D 由来列が NaN)B 全件を残したい
RIGHT OUTER JOIN (D 右)300 (D が部分集合のとき)D 全件を残したい (この例では INNER と同等)
FULL OUTER JOIN4717両側を全部残したい

D が完全に B の部分集合の場合、 RIGHT JOIN と INNER JOIN は同じ結果になる。 D に B にないキー (たとえば D に「東北地方」のような集約名が混じる) があると RIGHT JOIN は 30 行を超え、 FULL は 47 を超える。 つまり 結合方式の選び方は「B と D のどちらが部分集合か、 あるいは交差状態か」で決まる。 まず set(B.key) - set(D.key)set(D.key) - set(B.key) の両方を確認するのが、 結合事故ゼロへの第一歩。

❓ よくある質問(用語固有 10 連発)

汎用 FAQ 5 件に加えて、 外部結合 固有の質問 10 件を Q&A 形式でまとめた。 自分の状況に近いものから読んでほしい。

Q1. LEFT と RIGHT の違いは?
A. テーブルの位置だけ。 L LEFT JOIN RR RIGHT JOIN L。 慣習的に LEFT を使い、 「マスタは左に置く」スタイルが読みやすい。
Q2. FULL OUTER と UNION の違いは?
A. FULL OUTER JOINはキーでマッチした行を統合、 不一致は NULL 列。 UNIONは 2 テーブルを 縦に連結 (列構造が同じ必要)。 全く別の操作。
Q3. OUTER JOIN の結果が遅い
A. (i) 結合キーにインデックス、 (ii) 小さい側を右に置く (Hash Join 戦略)、 (iii) 事前フィルタでテーブルを縮小、 (iv) パーティション結合 (Spark)。
Q4. JOIN 後に NaN が大量に出る
A. 片側にしかないキーが多い証拠。 (i) キー前処理 (strip, lower, 型統一) で照合率を上げる、 (ii) indicator=True でどの側にあるか追跡、 (iii) 必要なら INNER に切替。
Q5. merge と join の違いは pandas で?
A. df.merge() は SQL 風の柔軟な結合 (任意の列をキーに)、 df.join() はインデックスベース。 通常は merge を使う。
Q6. 複合キーでの outer join は?
A. on=['都道府県', '年度'] のようにリスト指定。 SQL なら ON L.pref = R.pref AND L.year = R.year
Q7. 3 テーブル以上の outer join は?
A. a.merge(b, ...).merge(c, ...) と段階結合。 indicator も段階的に追加。 SQL なら FROM a FULL OUTER JOIN b USING(k) FULL OUTER JOIN c USING(k)
Q8. OUTER JOIN は INNER より遅い?
A. 原理的にはほぼ同じコスト (走査回数は同等)。 ただし結果行数が増えるので、 後段の処理で差が出る。 plan を必ず EXPLAIN で確認。
Q9. ANTI JOIN って何?
A. 「左にあって右に無い」行のみ返す結合。 LEFT OUTER + WHERE right.k IS NULL で実装。 SQL なら NOT EXISTS、 pandas なら merge + indicator=='left_only'
Q10. FULL OUTER は商用 RDB なら全部使える?
A. MySQL 8 系は標準で対応していない (UNIONでエミュレート)、 PostgreSQL/Oracle/SQL Server/SQLite は対応。 BigQuery/Snowflake 等の DWH は標準対応。

🏋️ 演習問題(5 問)

学習の定着には、 自分の手を動かすのが一番。 SSDSE-B-2026 や実ログを題材に、 外部結合 を実践する 5 問を用意した。 答えは Python 実装セクションと数値例セクションを参考に組み合わせれば導ける。

  1. 演習 1:SSDSE-B と SSDSE-D を都道府県名で full outer join し、 NaN 行数を indicator で集計せよ。
  2. 演習 2:結合前に str.strip().str.normalize('NFKC') でキー正規化、 表記揺れがマッチ率に与える影響を測れ。
  3. 演習 3:LEFT JOIN と RIGHT JOIN を入れ替えて結果が鏡像になることを確認せよ。
  4. 演習 4:3 つの SSDSE 表 (B, D, E) を full outer join し、 全表にあるキー・1 表のみのキー数を求めよ。
  5. 演習 5:suffixes を意味のあるラベルにして、 結合後に重複列名を分かりやすく区別せよ。

📌 演習を解いて疑問が残ったら、 「よくある質問」セクションに戻るか、 リポジトリの「論文一覧」から類似研究を探して、 実コード (本サイトには 159 本の再現論文) を読むのが最速の理解への道。

🛠 デバッグ手順書

外部結合 を使った分析で「結果がおかしい」と感じたとき、 上から順に確認してほしい 7 ステップ。

  1. 入力データの shape / dtype / 欠損df.info()df.isna().sum() で確認
  2. 1 サンプルを取り出し、 期待通りの計算が行われているか手計算と一致するか
  3. 境界ケース(空テーブル、 1 行のみ、 全 NaN)でエラーが出ないか
  4. 乱数シードを固定し、 同じ結果が再現できるか
  5. 中間結果print()logging で確認、 想定値からズレるところを特定
  6. 単体テストpytest で書き、 1 関数ずつ動作確認
  7. それでもダメなら、 最小再現コード (MRE) を作って Stack Overflow / GitHub Issue / 教員に質問

📌 デバッグは経験値が物を言う領域。 上記 7 ステップを習慣化することで、 1 件の事故で学ぶことが何倍にも増える。

🗺 学習パス:30 分 / 3 時間 / 30 時間

外部結合 をどの程度マスターするかで、 推奨する学習時間と内容が変わる。 自分の状況に合わせて選んでほしい。

⏱ 30 分:論文を読むだけ
  • 本ページの「💡 30 秒結論」「🎨 直感で掴む」「🔬 数式を言葉で読み解く(深掘り)」を順に読む
  • 論文に戻り、 該当箇所を再読
  • 分からない単語が出てきたら「🔗 関連用語」「🧭 用語クロスリンク集」から飛ぶ
⏱ 3 時間:手を動かす
  • 本ページの「🐍 Python 実装」「🐍 Python 実装(応用編)」を実際にコピペして動かす
  • 「🧪 SSDSE-B-2026 ハンズオン」を SSDSE 公式から CSV をダウンロードして実行
  • 「🏋️ 演習問題(5 問)」を最低 3 問解く
  • 結果を 外部結合 関連の落とし穴 8 件と照らし、 自分のコードに同じ事故がないか確認
⏱ 30 時間:教える側になる
  • 本ページの「📖 体系的解説 (5 観点)」を全部読み、 関連書籍を 1 冊精読
  • SSDSE 以外の実データ (例:自分の研究テーマや実務データ) で同じ分析を再現
  • 結果を 3 分プレゼンにまとめ、 同僚・後輩に説明 (アウトプット駆動)
  • 本ページの「🎬 ケーススタディ」のような「自分の事例」を 1 つ書き溜める
  • 関連論文 5 本を読み、 手法の発展と限界をマップ化

✅ 理解度セルフチェック(10 問)

本ページを読み終わったら、 以下の 10 問に □ チェックを入れて理解度を確認してほしい。 8 個以上 ✓ なら中級レベル、 全 10 個 ✓ なら他人に説明可能なレベル。

📌 チェックが付かない項目は、 該当セクションに戻って読み直してください。 「分かった気」と「分かっている」の境界を、 このリストで明確にします。

📖 専門用語ミニ辞書

本ページで頻出する周辺専門用語を、 1 行ずつ簡潔に。 ジャストインタイム的に、 必要なときだけ参照すれば良い。

SSDSE
独立行政法人統計センターが提供する「教育用標準データセット」。 公的データを基に、 学生・教育機関が使いやすく整形。
pandas
Python の表データ操作ライブラリ。 DataFrame 型が本ページのテーブル概念の主力実装。
CV (Cross Validation)
データを K 個に分割し、 K-1 個で学習・1 個で検証を K 回繰り返す。 性能評価の標準。
95% CI (信頼区間)
「真の値が含まれる範囲」を確率的に表現。 [L, U] の形で報告。
p 値
帰無仮説の下で、 観測値以上の極端な結果が出る確率。 通常 0.05 未満で「有意」。
OLS
Ordinary Least Squares、 最小二乗法。 回帰の基本。
SGD
Stochastic Gradient Descent、 確率的勾配降下法。 ML の標準最適化アルゴリズム。
RMSE / MAE
回帰評価指標。 Root Mean Squared Error / Mean Absolute Error。
AUC
Area Under Curve、 ROC 曲線下面積。 分類性能指標。
A/B テスト
2 つのバージョンを並列実装し、 ランダムにユーザーに当てて効果を測る実験。

📑 本サイトで 外部結合 を使う論文(抜粋)

本サイトには 159 本の再現論文があり、 多くが 外部結合 を何らかの形で利用している。 関連論文を読みたい方は 論文一覧 から検索してほしい。

📌 各論文は教育目的の再現実装で、 ハンズオン形式で読めるよう Jupyter Notebook 風の構成になっている。 「外部結合 を実際の研究でどう使うか」を 5 分で掴むには、 関連論文を 1 本流し読みするのが最速。

🤝 改善提案・誤り報告

本ページの内容に誤りや改善余地を見つけた場合、 リポジトリの Issue / Pull Request からご提案ください。 教材は みんなで育てるもの。

🍳 コード・クックブック(外部結合 編)

外部結合 を実務で使う際の頻出パターンを、 動くコードのレシピ集としてまとめた。 必要な料理 (タスク) だけを取り出して使ってほしい。

left / right / outer の 4 方式比較

1
2
3
4
5
6
import pandas as pd
a = pd.DataFrame({'k': ['x','y','z'], 'v_a':[1,2,3]})
b = pd.DataFrame({'k': ['y','z','w'], 'v_b':[20,30,40]})
for how in ('inner','left','right','outer'):
    m = a.merge(b, on='k', how=how, indicator=True)
    print(how, '\n', m, '\n')
📤 実行例(実測) inner k v_a v_b _merge 0 y 2 20 both 1 z 3 30 both left k v_a v_b _merge 0 x 1 NaN left_only 1 y 2 20.0 both 2 z 3 30.0 both right k v_a v_b _merge 0 y 2.0 20 both 1 z 3.0 30 both 2 w NaN 40 right_only outer k v_a v_b _merge 0 w NaN 40.0 right_only 1 x 1.0 NaN left_only 2 y 2.0 20.0 both 3 z 3.0 30.0 both

複合キーで結合 + 型統一

1
2
3
4
5
6
7
import pandas as pd
a = pd.DataFrame({'pref':['東京','大阪'], 'year':[2023, 2023], 'v_a':[1,2]})
b = pd.DataFrame({'pref':['東京', '大阪', '京都'], 'year':[2023.0, 2024.0, 2023.0], 'v_b':[10,20,30]})
# year が int と float で型不一致 → 結合失敗の可能性
b['year'] = b['year'].astype(int)
m = a.merge(b, on=['pref','year'], how='outer', indicator=True)
print(m)
📤 実行例(実測) pref year v_a v_b _merge 0 京都 2023 NaN 30.0 right_only 1 大阪 2023 2.0 NaN left_only 2 大阪 2024 NaN 20.0 right_only 3 東京 2023 1.0 10.0 both

巨大表を broadcast hint で結合 (Spark)

1
2
3
4
5
6
7
8
# from pyspark.sql import SparkSession
# from pyspark.sql.functions import broadcast
# spark = SparkSession.builder.appName('outer-join').getOrCreate()
# big = spark.read.parquet('data/processed/big_transactions.parquet')
# small = spark.read.parquet('data/processed/master.parquet')
# joined = big.join(broadcast(small), on='id', how='left_outer')
# print(joined.count())
# 上記疑似コード(Spark 環境で実行)。 broadcast hint で小表を全ノードに配布、 巨大表との外部結合を高速化。

📌 すべてのレシピは「実データ前提・引数なし直書き」スタイル。 そのままコピペで動くよう設計したので、 まずは動かしてから読むのを推奨する。

🚫 アンチパターン集

外部結合 を扱うコード・レポートで頻発するアンチパターンを 5 つ挙げる。 「やってはいけないこと」を知るのが、 良いコードへの近道。

❌ コピペで済ませて意味を理解しない
本ページのコードをコピペするのは OK だが、 「なぜそうなるか」を 1 度は手計算で確認すること。 デバッグ時に困る。
❌ 結果を 1 つの数字だけ報告する
「F1 = 0.82」「結合後 1,000 件」だけ報告するのはアンチパターン。 内訳・分散・前提条件を併記すること。
❌ 落とし穴を読まずに本番投入する
本ページの落とし穴 8 件はすべて「経験者が踏んだ地雷」。 本番前に必ず一読し、 自分のコードで該当しないか確認。
❌ ライブラリのデフォルトを盲信する
sklearn の average='binary'、 pandas の how='inner' 等のデフォルトは「最も多用される選択」であって「自分の目的に最適」とは限らない。 必ず確認。
❌ バージョン情報を記録しない
pandas / sklearn / torch のバージョンで挙動が変わることがある。 再現性のため pip freezeconda env export を記録。

🏁 最終結論:外部結合 を一言で

外部結合は「データ統合の最後の砦」。 内部結合で済むなら inner、 でも情報損失したくない場面で outer の出番が来る。 本ページで学んだ (i) リレーショナル代数の文脈、 (ii) Left/Right/Full の使い分け、 (iii) NaN の意味論、 (iv) data skew 対策、 (v) indicator で由来追跡の 5 原則を持って結合すれば、 「結合後の件数が膨張した」「NaN だらけになった」「速度が極端に遅い」の 3 大事故を防げる。 47 都道府県の SSDSE のような小データから、 1 億行のクラウド DWH まで、 概念は同じ。

本ページは ジャストインタイム型データサイエンス教育の一部として、 必要なときに必要な節だけ読んでもらう設計になっている。 通読する必要はない。 自分の今いる場所 (卒論・実務・論文読解) に応じて、 該当セクションだけを参照し、 また論文や業務に戻ってほしい。 そして数か月後、 似たような状況に陥ったとき、 また戻ってきてくれれば、 教材として最高の使い方になる。

📚 関連リンク:論文一覧 | 用語集トップ | 概念マップ

🙋 著者・教材設計について

本教材は、 広島工業大学 統計・データ解析コンペティション参加学生向けに、 松本伸平 (s.matsumoto.gk@cc.it-hiroshima.ac.jp) が監修・執筆した。 「論文を読む過程で出てきた専門用語を、 その場で 5 分で補完して論文に戻る」というジャストインタイム型の学習体験を目的に、 514 用語ページを統一フォーマットで整備している。

本ページ「外部結合」は データエンジニアリング カテゴリに属し、 同カテゴリ内の他用語と相互リンクされている。 用語間の関係性は 概念マップ でも俯瞰できる。

本サイトは SSDSE (教育用標準データセット, 独立行政法人統計センター) を主データとして使い、 「合成データ ではなく実公的データを使う」 を方針に据えている。 ハンズオン教材の質を最大化するための判断である。

outer join 外部結合 日本語 英語 中国語 ドイツ語 フランス語

🔗 隣接手法への橋渡し

「外部結合」は単独で完結せず、 前後の手法と組み合わさって価値が発揮される。 入力データの準備 (上流)・同目的の代替手法との比較 (並列)・結果の活用 (下流) という 3 軸で隣接領域を整理する。

この上流・並列・下流の対応を地図化することで、 「外部結合」を中核に据えた分析パイプライン (データ準備 → 手法選択 → 結果の検証と展開) の全体像が見えてくる。

🌳 手法選択フロー

「外部結合」を実際に使うとき、 何をどう選ぶかを順に判断する。 上から順に答えていくと、 使うべき手法と評価の仕方が決まる。

  1. 片方にしか無い行をどう扱うか
    残すなら外部結合、 落とすなら内部結合。 「落としたつもりが無い」まま内部結合すると、 行が静かに減る。 結合前後で行数を必ず数える。
  2. どちら側を残すか
    左を全部残すなら LEFT、 両方なら FULL OUTER。 「マスタに無いコードが来ていないか」を調べたいなら、 あえて外部結合して欠測を見る。
  3. キーは一意か
    結合キーが重複していると、 行数が掛け算で増える。 SSDSE-B-2026 を地域コードだけで結合すると、 12 年分が掛かって 12 倍になる。 結合前に duplicated() で確認する。
  4. 欠測をどう埋めるか
    外部結合で生じた NaN は「値が無い」であって 0 ではない。 0 で埋めてよいかは、 その列が件数なのか金額なのか比率なのかで変わる。

外部結合は「合わなかった行」を可視化する道具でもある。 結合してから欠測を数えると、 データの不整合が見つかることが多い。