Power Query 実務テンプレ | クレンジング(前処理)系:重複行削除(全列)

Excel VBA Power Query M Formula Language
スポンサーリンク

ゴールのイメージをそろえる

今回のテーマは「Power Query で テーブル全体を見て“完全に同じ行”を重複として削除する実務テンプレ」です。
ここでいう「重複行削除(全列)」は、

「1行まるごと、すべての列の値が同じ行は、1件だけ残して他は消す」

という意味です。

「キー列だけで重複判定」ではなく、「全列一致で重複判定」するパターンなので、
“インポートした生データから、まるっと同じ行を落としたい”ときに使います。


まず「どんな重複」を消したいのかを具体化する

例題データをイメージする

次のようなテーブルを想像してください。

受注番号顧客コード商品コード数量金額
1001C001A001101200
1001C001A001101200
1002C002A0025800
1003C003A0033600
1003C003A0033600

ここで「完全に同じ行」が2つずつあります。

1行目と2行目は、全列の値が完全一致。
4行目と5行目も、全列の値が完全一致。

やりたいことは、

「1001 の行は 1件だけ残す」
「1003 の行も 1件だけ残す」

つまり、「全列が同じ行は 1件だけ残して、残りを削除する」ということです。


基本テンプレ:Table.Distinct で「全列重複」を削除する

もっともシンプルな書き方

Power Query には、重複行を削除するための Table.Distinct という関数があります。
「全列で重複判定したい」場合は、列指定を省略すれば OK です。

let
    Source = ・・・前のステップ・・・,

    RemovedDuplicates =
        Table.Distinct(Source)
in
    RemovedDuplicates
Power Query

これだけで、「テーブル全体を見て、完全に同じ行は 1件だけ残す」という動きになります。

先ほどの例なら、結果はこうなります。

受注番号顧客コード商品コード数量金額
1001C001A001101200
1002C002A0025800
1003C003A0033600

「どの行を残すか」は、元の順番に依存します。
同じ内容の行が複数あっても、最初に出てきた行が残り、後ろの分が削除されます。


重要ポイント1:「全列一致」であることが前提になる

1つでも違う列があれば「別の行」とみなされる

Table.Distinct(Source) は、「全列の値がすべて同じかどうか」で重複判定します。
つまり、1列でも違えば「別の行」として残ります。

例えば、次の2行はどうでしょう。

受注番号顧客コード商品コード数量金額
1001C001A001101200
1001C001A001101200.0

見た目は同じでも、型や値が微妙に違うと「別物」として扱われることがあります。
また、次のようなパターンも同様です。

“1200”(文字列)と 1200(数値)
” C001″(前にスペースあり)と “C001”
“2024/01/01″(文字列)と #date(2024,1,1)(日付型)

「全列一致で重複判定する」前に、
型変換・トリム・カンマ削除・日付変換などのクレンジングを済ませておくと、
“意図した通りの重複削除”になりやすくなります。


重要ポイント2:「どの行を残すか」をコントロールしたい場合

先にソートしてから Table.Distinct する

Table.Distinct は、「最初に出てきた行を残し、後ろの重複を削除する」という動きをします。
ということは、「どの行を残したいか」をコントロールしたければ、
先にソートしておけばいい、ということです。

例えば、次のようなケースを考えます。

同じ内容の行が複数あるが、「更新日時が一番新しい行だけ残したい」。

この場合は、

更新日時で降順ソートする(新しいものが上に来るように)。
そのあとで Table.Distinct する。

という順番にします。

let
    Source = ・・・前のステップ・・・,

    Sorted =
        Table.Sort(
            Source,
            {{"更新日時", Order.Descending}}
        ),

    RemovedDuplicates =
        Table.Distinct(Sorted)
in
    RemovedDuplicates
Power Query

こうすると、「同じ内容の行が複数ある場合は、更新日時が一番新しい行だけが残る」という動きになります。
“どの行を残すか”を意識できているかどうかで、実務の精度がかなり変わります。


重要ポイント3:NULL や空白も「値の一部」として判定される

NULL を含む行の重複判定

Table.Distinct は、NULL も「値の一つ」として扱います。
つまり、次の2行は「完全に同じ」とみなされます。

受注番号顧客コード商品コード数量金額
1001C001null101200
1001C001null101200

一方、次の2行は「別の行」です。

受注番号顧客コード商品コード数量金額
1001C001“”101200
1001C001null101200

空文字(””)と NULL は別物だからです。

「空文字は全部 NULL に統一してから重複判定したい」
「NULL は残したくないので、先に除外してから重複削除したい」

など、NULL や空白の扱いを先に決めておくと、
“想定外に重複が残る/消える”という事故を防げます。


実務テンプレとしての流れをまとめる

クレンジングと重複削除の組み合わせ

実務で「全列重複削除」を使うときは、だいたい次の流れが安定します。

1つ目のステップで、型変換(数値・日付・テキスト)をそろえる。
2つ目のステップで、トリム・全角→半角・改行削除・不正文字除去などを行う。
3つ目のステップで、必要ならソート(残したい行を上に持ってくる)。
4つ目のステップで、Table.Distinct による「全列重複削除」。

この順番にしておくと、

見た目は同じなのに空白や全角の違いで重複判定がズレる
残したい行ではない方が残ってしまう

といった“よくあるハマり”をかなり避けられます。


実務テンプレとしてのまとめ

「重複行削除(全列)」の本質は、とてもシンプルです。

Table.Distinct(Source) で、「全列の値が完全一致する行は 1件だけ残す」。
残したい行をコントロールしたければ、先にソートしてから Table.Distinct する。

そして、より重要なのはその前段階——
型変換・トリム・NULL/空白の統一などのクレンジングを済ませてから重複削除する、という“順番の設計”です。

ここまでの前処理テンプレ(トリム、全角→半角、改行削除、不正文字除去、日付・数値変換)と、
今回の「全列重複削除」を組み合わせると、
かなり“信頼できるユニークな明細テーブル”を作れるようになります。

タイトルとURLをコピーしました