Power Queryの「クエリのマージ」は、2つの表を共通のキー列で照合し、もう一方の表の列を横に付け足す機能です。どの行が残るかは、選ぶ結合の種類で変わります。この記事では、小さな表で6種類の結果を比べ、目的に合う種類の選び方を説明します。行が増えてしまうときや、一致しないときの確認方法も扱います。
なお、同じ形式の表を縦につなぐのは「クエリの追加」で、マージとは別の機能です。
例に使う2つの表
マージの画面で上に置く表を「最初のテーブル」、下に置く表を「2番目のテーブル」と呼びます。ここでは注文一覧を最初のテーブル、顧客マスタを2番目のテーブルにして、顧客IDで照合します。
最初のテーブル:注文
| 注文No | 顧客ID | 金額 |
|---|---|---|
| 1 | C01 | 1,000 |
| 2 | C02 | 2,000 |
| 3 | C04 | 1,500 |
| 4 | C01 | 800 |
2番目のテーブル:顧客
| 顧客ID | 顧客名 |
|---|---|
| C01 | 山田商店 |
| C02 | 佐藤工業 |
| C03 | 鈴木食品 |
注文3の顧客ID(C04)は顧客マスタにありません。また、顧客C03には注文がありません。
6種類の結合で残る行
| 結合の種類 | 残る行 | 例の結果 | 主な用途 |
|---|---|---|---|
| 左外部 | 最初のテーブルの全行。2番目のテーブルに一致する行があれば、その列を付ける | 4行(注文1〜4。注文3の顧客名は空) | マスタから名前や単価を付ける。元の行を減らしたくないとき |
| 右外部 | 2番目のテーブルの全行。最初のテーブルに一致する行があれば、その列を付ける | 4行(注文1・2・4と、注文のないC03) | 2番目の表を中心に見たいとき |
| 完全外部 | 両方のテーブルの全行 | 5行(注文1〜4とC03) | 2つの一覧を全体として突き合わせるとき |
| 内部 | 両方に一致がある行だけ | 3行(注文1・2・4) | 両方にそろったデータだけを使うとき |
| 左反 | 最初のテーブルのうち、2番目に一致がない行だけ | 1行(注文3) | マスタに登録がない注文を探す |
| 右反 | 2番目のテーブルのうち、最初に一致がない行だけ | 1行(C03) | 注文のない顧客を探す |
「左」「右」は、マージ画面の上下(最初・2番目)のどちらを基準にするかを表します。最初と2番目のテーブルを入れ替えると、左外部と右外部、左反と右反の結果も入れ替わります。
左外部の結果
顧客名の列を展開すると、次のようになります。一致しなかった注文3も残り、顧客名は null(空)になります。
| 注文No | 顧客ID | 金額 | 顧客名 |
|---|---|---|---|
| 1 | C01 | 1,000 | 山田商店 |
| 2 | C02 | 2,000 | 佐藤工業 |
| 3 | C04 | 1,500 | null |
| 4 | C01 | 800 | 山田商店 |
内部の結果
注文3がなくなり、3行になります。
| 注文No | 顧客ID | 金額 | 顧客名 |
|---|---|---|---|
| 1 | C01 | 1,000 | 山田商店 |
| 2 | C02 | 2,000 | 佐藤工業 |
| 4 | C01 | 800 | 山田商店 |
内部結合では、一致しなかった行が何の表示もなく消えます。金額を集計する表で使うと、注文3の1,500円が合計から抜けても気付きにくくなります。内部結合を使うときは、次の左反結合で、消えた行を確認しておくと安全です。
左反の結果
注文3だけが残ります。2番目のテーブルに一致する行がないので、展開しても顧客名はすべて null です。左反結合では、マージで追加された列は展開せずに削除して使うのが一般的です。
| 注文No | 顧客ID | 金額 |
|---|---|---|
| 3 | C04 | 1,500 |
右外部・完全外部ではキー列に注意
右外部や完全外部では、2番目のテーブルにしかない行(例のC03)の、最初のテーブル側の列はすべて null になります。最初のテーブルの「顧客ID」列だけを見ると、C03の行はキーが空です。展開するときは2番目のテーブルの顧客IDも一緒に取り出し、必要なら「空でない方の値を使う」列を作ります。カスタム列の式は、たとえば次のように書きます(列名は展開後の名前に合わせてください)。
if [顧客ID] = null then [顧客.顧客ID] else [顧客ID]
マージの後は、行の並び順が元の表と変わることがあります。順番が必要なら、マージの後に並べ替えのステップを入れてください。
マージの操作手順
- Power Queryエディターで、最初のテーブルにするクエリ(例では注文)を選びます。
- 「ホーム」タブの「クエリのマージ」を選びます。元のクエリを残して別のクエリとして作りたいときは、「新規としてクエリをマージ」を選びます。
- 上が最初のテーブルです。下のドロップダウンで2番目のテーブルを選びます。
- 上と下の表で、それぞれキーにする列の見出しをクリックします。複数の列を組み合わせてキーにするときは、Ctrlキーを押しながら、上下で同じ順番にクリックします。
- 「結合の種類」で目的の種類を選びます。
- 画面の下に、最初のテーブルの何行が一致したかを示すメッセージが出ます。一致が想定より少ない場合は、ここで止めてキー列を確認します。
- 「OK」を押すと、2番目のテーブルの内容が入った列が追加されます(各行に「Table」と表示されます)。列見出しの展開ボタンを押し、必要な列だけにチェックを入れて展開します。「元の列名をプレフィックスとして使用します」のチェックを外すと、列名の先頭に「顧客.」が付きません。ただし、最初のテーブルにある列と同じ名前の列を展開するときは、プレフィックスを残すか名前を変えてください。
マージのステップは、数式バーでは次のような式になります。
= Table.NestedJoin(注文, {"顧客ID"}, 顧客, {"顧客ID"}, "顧客", JoinKind.LeftOuter)
最後の引数が結合の種類で、次の6つのどれかが入ります。
- JoinKind.LeftOuter(左外部)
- JoinKind.RightOuter(右外部)
- JoinKind.FullOuter(完全外部)
- JoinKind.Inner(内部)
- JoinKind.LeftAnti(左反)
- JoinKind.RightAnti(右反)
画面で選び直す代わりに、ここを書き換えても種類を変えられます。
目的から結合の種類を選ぶ
- 元の表の行数はそのままで、マスタの情報を付けたい:左外部を選びます。一致しない行は null になるので、null の件数を確認します。
- 両方にそろったデータだけで集計したい:内部を選びます。ただし、消えた行は左反で別に確認します。
- マスタにない値や、相手の一覧にない値を探したい:左反または右反を選びます。
- 2つの一覧全体を突き合わせ、片方にしかない行も並べて見たい:完全外部を選びます。
迷ったら、まず左外部で結合し、null になった行を見てから絞り込みます。こうすると、何が落ちたかを見失いにくくなります。
行が増えたとき:2番目のテーブルのキーが重複している
左外部で結合したのに、結合後の行数が最初のテーブルより増えることがあります。主な原因は、2番目のテーブルに同じキーの行が複数あることです。
たとえば顧客マスタに、C01が次のように2行あるとします。
| 顧客ID | 顧客名 |
|---|---|
| C01 | 山田商店 |
| C01 | 山田商店(旧) |
| C02 | 佐藤工業 |
| C03 | 鈴木食品 |
この状態で左外部結合して展開すると、C01の注文1と注文4が2行ずつになり、4行だった注文が6行になります。金額を合計すると、注文1と注文4は二重に数えられます。
確認方法は次のとおりです。
- キーの重複を数える:2番目のテーブルのクエリで顧客ID列を選び、「ホーム」タブの「グループ化」で行数を数えます。行数が2以上のキーだけにフィルターすると、重複しているキーが分かります。
- 一致数の列を作る:マージした直後(展開する前)に、
Table.RowCount([顧客])というカスタム列を追加します。各行がいくつの行と一致したかが分かり、1より大きい行が増える原因です。0の行は一致しなかった行です。[顧客] の部分は、マージで追加された列の名前に合わせます。 - 列のプロファイルを見る:「表示」タブで「列のプロファイル」をオンにし、キー列の個別の値の数と行数を比べます。個別の値の数が行数より少なければ、重複があります。プロファイルは既定では先頭1,000行だけで集計されます。画面下のステータスバーで「データセット全体に基づく列のプロファイル」に切り替えてから見てください。
直し方は、重複している理由によって変わります。
- マスタの登録ミスなら、マスタ側を直すのが根本的な対処です。
- 古い行と新しい行が混ざっている場合は、どちらを残すか(更新日の新しい方など)を決めてから重複を除きます。Power Queryの重複の削除は、並び順によって残る行が変わることがあるので、残す行を決める条件を先に作っておきます。
- 1対多が正しい関係(注文と明細など)なら、行が増えるのは正しい結果です。合計する列がどちらの表の値なのかを確認し、二重に数えないように集計します。
一致しないとき:型・空白・大文字小文字を確認する
キーが見た目では同じなのに一致しない場合は、次の順に確認します。
| 確認すること | よくある例 | 直し方 |
|---|---|---|
| データ型 | 一方が文字列の "001"、もう一方が数値の 1 | 両方のキー列を同じ型にそろえる(コードなら通常はテキスト)。数値型にした時点で先頭の0は消えているので、元の列から型を設定し直す |
| 前後の空白・改行 | "C01 " のように末尾に空白がある | 「変換」タブの「書式」から「トリミング」「クリーン」を実行する |
| 大文字と小文字 | "c01" と "C01" | 通常のマージでは別の値として扱われる。「書式」の「大文字」などで両方をそろえる |
| 全角と半角 | "C01" と "C01" | 見た目が似ていても別の値になる。元データの表記を統一するか、置換でそろえる |
| 空のキー | キー列が null や空文字の行 | 思わぬ一致や不一致の原因になる。先に件数を確認し、除外するか扱いを決める |
一致しない行を具体的に見るには、左反結合が便利です。残った行に Text.Length([顧客ID]) のカスタム列を追加すると、見えない空白で文字数が多くなっている行を見つけやすくなります(キー列が数値型なら、先にテキストに変えます)。
マージ画面には「あいまい一致を使用してマージを実行する」という選択肢もあります。表記ゆれも含めて照合できますが、似ているだけの別の値まで一致させることがあります。金額や請求に関わる照合では、まずキーを整えてから通常のマージを使ってください。あいまい一致を使う場合は、結果を1件ずつ確認します。
マージ後に確認すること
- 結合後の行数が、選んだ種類から予想した行数と同じか(左外部なら、2番目のテーブルのキーに重複がなければ、最初のテーブルと同じ行数になる)
- 左外部で一致しなかった行(一致数が0の行)の数が、同じキーで左反結合したときの行数と同じか
- 左外部の場合、金額などの合計が、結合前の最初のテーブルの合計と同じか
- 内部結合を使った場合、消えた行を左反結合で一覧にし、落としてよい行かどうかを確かめたか
