
- はじめに ── Power Queryには「多対多警告」がない
- 事前チェック:マージする前にキーの一意性を検査する
- 事後チェック:マージした後に異常を発見する
- 事前チェックと事後チェック、結局どちらをやるべきか
- まとめ
はじめに ── Power Queryには「多対多警告」がない
Power Queryでテーブルをマージするとき、Excelのように「このマージは多対多になります」と警告してくれる機能は存在しません。
そのため、実務では
- マージ前に異常を防ぐ「事前チェック」
- マージ後に異常を発見する「事後チェック」
の2段構えで、自分で検査の仕組みを組み込む必要があります。
この記事では、この2つのアプローチを順番に紹介します。
| 目的 | タイミング | 実装方法 | |
|---|---|---|---|
| 事前チェック | キー候補が本当に一意かを確認する | マージ前 | 自作関数(fxCheckKey) |
| 事後チェック | マージ結果に異常(多対多・未登録)がないかを確認する | マージ後 | 一致件数列+GUI操作 |
どちらか一方でも効果はありますが、両方組み合わせると、キー設計ミスと実データの異常の両方を検出できます。
事前チェック:マージする前にキーの一意性を検査する
基本の運用:検査クエリを2種類用意する
マージするすべてのクエリについて、次の2つを用意します。
- 取引先データ
- 検査取引先データキー重複
- 調達実績データ
- 検査調達実績データキー重複
検査クエリでは、キー候補列(例:契約番号/明細番号/年度)で Group By を行い、
件数 > 1
だけを抽出します。
- 結果が 0行 → このキーは一意
- 結果が 1行以上 → 重複あり(キー不足の疑い)
レビュー時のチェックポイント:キーに使われていない列はないか
マージ画面で契約番号・明細番号のみがキーとして選択されているのに、両方のテーブルに「年度」列が存在している――このような状態を見つけたら要注意です。
「年度があるのにキーに使われていない」こと自体が、レビュー時の重要なチェックポイントになります。
汎用「主キー検査関数」を自作する
データベースでは主キー制約が自動で重複を防いでくれますが、Power Queryにはその機能がありません。そこで、汎用的に使える検査関数を自作します。
全体イメージ
例えば次のような取引先データがあるとします。
| 契約番号 | 明細番号 | 年度 | 取引先 |
|---|---|---|---|
| O1 | 1 | 2025 | A |
| O1 | 1 | 2026 | A |
| O2 | 1 | 2025 | B |
このテーブルに対して
fxCheckKey(
取引先データ,
{"契約番号","明細番号"}
)
と呼べば「重複あり」、
fxCheckKey(
取引先データ,
{"契約番号","明細番号","年度"}
)
と呼べば「一意」と返ってきます。列名を変えるだけで、どんなテーブルにも使い回せます。
ステップ1:空のクエリを作る
「ホーム」→「新しいソース」→「空のクエリ」を作成し、クエリ名を fxCheckKey に変更します。
ステップ2:詳細エディターに関数を記述する
既存の内容を全て削除し、以下を貼り付けます。
(tbl as table, KeyColumns as list) as table =>
let
Grouped =
Table.Group(
tbl,
KeyColumns,
{
{"件数", each Table.RowCount(_), Int64.Type}
}
),
Result =
Table.AddColumn(
Grouped,
"判定",
each if [件数]=1 then "一意" else "重複あり"
)
in
Result
これだけで関数は完成です。
ステップ3:関数を呼び出す
新しい空クエリを作り、以下のように呼び出します。
= fxCheckKey(
#"取引先データ",
{"契約番号","明細番号"}
)
結果:
| 契約番号 | 明細番号 | 件数 | 判定 |
|---|---|---|---|
| O1 | 1 | 2 | 重複あり |
| O2 | 1 | 1 | 一意 |
キーに「年度」を追加すると:
= fxCheckKey(
#"取引先データ",
{"契約番号","明細番号","年度"}
)
| 契約番号 | 明細番号 | 年度 | 件数 | 判定 |
|---|---|---|---|---|
| O1 | 1 | 2025 | 1 | 一意 |
| O1 | 1 | 2026 | 1 | 一意 |
ステップ4:判定列でフィルターする
「判定」列を「重複あり」だけに絞り込めば、原因行だけが残ります。これだけでも十分実務に使えます。
一歩進めた活用:最小キーの候補を一覧化する
実務では「何列そろえれば一意になるのか」を知りたくなる場面があります。
| 候補 | 結果 |
|---|---|
| 契約番号 | × |
| 契約番号・明細番号 | × |
| 契約番号・明細番号・年度 | ○ |
| 契約番号・年度 | × |
| 契約番号・製品番号 | × |
このように候補を一覧化しておくと、「このテーブルの最小キーは契約番号+明細番号+年度である」ということが一目で分かります。
実務で一番使うバージョン:重複行だけを返す関数
さらに改良し、「重複行だけを返す」関数にしておくと運用が楽になります。
(tbl as table, KeyColumns as list) as table =>
let
Grouped =
Table.Group(
tbl,
KeyColumns,
{
{"件数", each Table.RowCount(_), Int64.Type}
}
),
Duplicates =
Table.SelectRows(
Grouped,
each [件数] > 1
)
in
Duplicates
この関数であれば、
- 問題なし → 0行
- 問題あり → 重複キーだけ表示
という結果になるため、「更新のたびに結果が0行であればOK」というシンプルな運用チェックが可能になります。
事後チェック:マージした後に異常を発見する
事前チェックはキー候補の設計段階でのミスを防ぐものですが、実際にマージを実行した後でなければ見えてこない異常もあります。ここでは、GUI操作だけで完結する「一致件数チェック」を紹介します。
この方法は、
- キー不足(今回のような年度の入れ忘れ)
- マスタ未登録
- マスタ重複
をすべて同時に検出できるのが特徴です。
ステップ1:マージを行う(あえてキーは不足させたまま)
現在のように契約番号・明細番号でマージします(わざと年度は入れません)。結合の種類は左外部結合です。
すると新しい列「取引先データ」ができます。まだ展開しません。
| 契約番号 | 明細番号 | 年度 | 取引先データ |
|---|---|---|---|
| O1 | 1 | 2025 | Table |
| O2 | 1 | 2025 | Table |
| … |
ステップ2:一致件数列を追加する
リボンから「列の追加」→「カスタム列」をクリックします。
- 新しい列名:
一致件数 - 数式:
Table.RowCount([取引先データ])
OKを押すと、次のようになります。
| 契約番号 | 年度 | 取引先データ | 一致件数 |
|---|---|---|---|
| O1 | 2025 | Table | 2 |
| O2 | 2025 | Table | 1 |
| O3 | 2025 | Table | 1 |
今回はO1だけが「2」になっています。この時点で「1件じゃない!」と気付けます。
ステップ3:異常だけ表示する
一致件数列の▼を押し、「数値フィルター」→「等しくない」→「1」を指定します。
すると
| 契約番号 | 一致件数 |
|---|---|
| O1 | 2 |
だけが残ります。これがマージ異常一覧です。
ステップ4:原因を確認する
ここで初めて「取引先データ」列の Table をクリックします。すると2025・2026の2行が入っていることが分かり、「あ、年度がキーに入ってない」と原因が判明します。
ステップ5:修正する
マージを編集し、契約番号・明細番号・年度の3列でマージし直します。
ステップ6:もう一度一致件数を確認する
今度は次のようになります。
| 契約番号 | 一致件数 |
|---|---|
| O1 | 1 |
| O2 | 1 |
| O3 | 1 |
これで正常です。
ステップ7:完成テーブルを作る
一致件数が全て1であることを確認したら、最後に「取引先データ」列を展開します。これで完成です。
実務ではさらにおすすめ:検査専用クエリを分離する
私は検査用クエリを別に1つ作ってしまいます。
調達実績+取引先(マージ)
│
├── 完成データ
│
└── マージ検査
マージ検査クエリでやることは、
- 一致件数列を追加する
- 一致件数≠1 だけ残す
の2ステップだけです。
- 0件 → マスタ未登録
- 2件以上 → キー不足・重複
だけが表示されます。
通常運用ではこの「マージ検査」クエリは0行になります。0行であれば「異常なし」、1行以上表示されたら「マージ条件またはマスタデータを確認する」という運用にすると、データ更新時のチェックが非常に簡単になります。
事前チェックと事後チェック、結局どちらをやるべきか
両者は役割が異なるため、併用をおすすめします。
- 事前チェック(fxCheckKey):クエリ設計・レビューの段階で「このキーは本当に一意か」を確認する。設計ミスを開発時点でつぶせる。
- 事後チェック(一致件数クエリ):日々のデータ更新時に「今回のデータで異常が起きていないか」を機械的に確認する。マスタ側の欠落・重複など、データそのものの異常にも気付ける。
事前チェックは「作るとき」、事後チェックは「動かすたび」に効いてくる、という住み分けで考えると分かりやすいです。
まとめ
- Power Queryにはマージ時の多対多を警告する機能がないため、自分で検査の仕組みを作る必要がある
- 事前チェック:自作関数
fxCheckKeyでキー候補の一意性を設計段階で検査する - 事後チェック:一致件数列(
Table.RowCount)をGUI操作だけで追加し、マージ後の異常(多対多・マスタ未登録)を検出する - 事後チェックは「マージ検査」クエリとして分離しておくと、更新のたびに0行であることを確認するだけの運用にできる
- 最終的には「キーに使われていない識別列がないか」をレビューで確認する習慣も重要








