Zoho CRMの重複チェックとは、CRMに入ってくるデータが、すでに登録されている人や会社と同じかどうかを調べることです。調べた結果をどう扱うか(自動で統合するか、印を付けて人が判断するか)まで含めて設計します。
この記事では、寄付で活動する非営利法人のZoho CRMで、当社が寄付者データの重複チェックを設計したときの考え方をまとめます。結論は「自動マージ(自動での統合)はしない」です。打ち合わせの中で自動マージも選択肢に挙がりましたが、見送りました。その理由と、代わりにどう運用するかを説明します。
重複チェックは、取込前に住所・電話番号・氏名などの値をそろえる正規化が済んでいる前提で動きます。
なぜ自動マージ(重複の自動統合)を見送ったのか
寄付者のデータは、寄付決済サービス、クラウドファンディング、ネット募金、物品の寄付、自団体のフォームなど、多くの入口から入ってきます。同じ人が複数の入口から寄付すれば、CRMには同じ人が何件も登録されます。これを機械で自動的に1件にまとめられれば楽に見えます。
見送った理由は3つです。
- すべての項目で「どちらを残すか」を決めきれない。 2件を1件にまとめるには、住所・電話番号・送り先・寄付の種類・メール配信の可否など、全項目で残す値の優先順位を決める必要があります。打ち合わせでも、自動マージをするなら項目の優先順位を完全に決めなければならない、という点が論点になりました
- 間違えたときの被害が大きい。 別人を1人にまとめると、寄付の履歴や郵送物の送り先が混ざります。寄付者名簿や領収書に関わるデータなので、誤りが外に出るおそれがあります
- 一致の手がかりが弱い。 氏名の一致は同姓同名の別人かもしれません。メールアドレスも、家族で共有していることがあります
そこで、見つけるところまでを機械が行い、まとめるかどうかは人が決める、という分担にしました。
Zoho CRMにも、指定した項目(最大3つ)の値が同じレコードをまとめて統合する「重複データの統合(De-duplicate)」の機能があります。公式ヘルプには、統合後に残るレコードは最終活動日時が最も新しいものが自動で選ばれ、統合した重複レコードは削除されて元に戻せないと書かれています(De-duplicate records (Auto-merge duplicates))。取込元によって情報の新しさや正しさが違うデータでは、この選び方が合わないことがあります。
「上書き更新」と「統合」を分けて考える

自動処理を全部やめたわけではありません。分けて考えたのは次の2つです。
| 上書き更新 | 統合(マージ) | |
|---|---|---|
| 何をするか | 既存の1件に、新しい情報を書き込む | 既存の2件を1件にまとめる |
| 前提 | 照合に使う番号が1人に1つと保証されている | 2件が同じ人だと判断できている |
| この案件での扱い | 条件を満たせば自動 | 必ず人が判断する |
継続寄付のデータには、寄付サービスが寄付者ごとに発行する会員番号が付いています。この番号は1人に1つで変わらないため、番号が一致したら既存の連絡先を自動で上書きし、重複フラグは付けません。
一方、単発の寄付にも番号は付いていましたが、それが「寄付ごと」の番号なのか「人ごと」の番号なのかが、仕様書を作った時点では分かりませんでした。寄付サービスの運営元に確認している間は、暫定でメールアドレスで照合し、重複フラグを付けて人が確認する扱いにしました。
ここでの教訓は、番号があるだけではキーにしないことです。1人に1つで、あとから変わらないことを確かめてから、自動処理のキーにします。
取込元ごとの判定キー
取込元ごとに、何で照合し、一致したらどうするかを表にしました。
連絡先(個人)
| 取込元の種類 | 照合に使う項目 | 一致したとき |
|---|---|---|
| 寄付決済サービス(継続寄付) | 寄付者ごとの会員番号 | 自動で上書き更新 |
| 寄付決済サービス(単発寄付) | メールアドレス(暫定) | 重複フラグを付ける |
| クラウドファンディング | メールアドレス | 重複フラグを付ける |
| ネット募金(メールあり) | メールアドレス | 重複フラグを付ける |
| ネット募金(メールなし) | 氏名(姓と名をつなげたもの) | 重複フラグを付ける |
| 物品の寄付・その他の寄付サービス | メールアドレス | 重複フラグを付ける |
| 手入力・フォーム | メール・電話番号・氏名のそれぞれ | 一致した理由ごとにフラグを付ける |
取引先(法人)
| 取込元の種類 | 照合に使う項目 | 一致したとき |
|---|---|---|
| 寄付決済サービスの法人データ | 会員番号 | 自動で上書き更新 |
| 支援団体・メディアなどの取込 | 法人名 | 重複フラグを付ける |
| 手入力 | 法人名 | 重複フラグを付ける |
寄付決済サービスの法人データは、仕様では「法人名+部署」の組み合わせで1件として管理することにしました。
重複チェックの精度を上げるには、比べる前に何をそろえるか
重複チェックの精度は、比べる値がそろっているかで決まります。次の3つを守ります。
- 空の値は比べない。 メールアドレスが空のデータ同士が「一致」と判定されると、空のデータがすべて重複候補になってしまいます
- 全角と半角をそろえてから比べる。 「test@example.com」と「
test@example.com」は同じです - 英字の大文字と小文字をそろえてから比べる。 メールアドレスの大文字・小文字の違いで別人扱いにしないためです
この3つは、正規化と同じ関数の中で、重複チェックの直前に行います。仕様でも、作成時に動く関数の中で「正規化→重複チェック」の順に処理する形にしました。別々の関数を別々のワークフローで動かすと、どちらが先に動くかを決められず、正規化の前の値で比べてしまうおそれがあります。片方の規則だけ変わって判定がずれることも防げます。
重複フラグはなぜ「理由ごと」に付けるのか
重複が見つかったら、どの項目が一致したかが分かる形で印を付けます。この案件では、タグを理由ごとに分けました。
- メール重複の可能性あり
- 姓名重複の可能性あり
- 電話番号重複の可能性あり
- 法人名重複の可能性あり
複数の項目が一致すれば、タグも複数付きます。メール・電話・氏名の3つが同じなら同じ人の可能性が高く、氏名だけなら別人の可能性もある、というように、確認する人が一致の強さをひと目で判断できることが理由ごとに分ける目的です。
Delugeのコード例(searchRecordsで候補を探す)
連絡先の作成時にワークフローから呼ぶ関数の例です。この例では、タグの代わりに「重複フラグ」(チェックボックス)、「重複の理由」(複数選択)、「重複候補のID」(テキスト)の3項目に書き込みます。項目にしておくと、一覧やレポートの条件に使いやすいためです。項目のAPI名は一般的な名前に置き換えています。
下のコードは、重複チェックの部分だけを抜き出したものです。正規化(全角半角・大文字小文字)は、正規化の記事の関数の処理を、同じ関数の前半に入れて先に済ませる前提です。関数の1行目(関数名と引数)は、関数を作る画面で引数(連絡先のIDを文字列で受け取る contactId)を設定すると入ります。
void automation.CheckDuplicateContact(string contactId)
{
rec = zoho.crm.getRecordById("Contacts",contactId.toLong());
if(rec.get("id") == null)
{
info "連絡先が取得できませんでした: " + contactId;
return;
}
reasons = List();
candidateIds = List();
// 検索条件を壊す記号(括弧・カンマ)を除く
email = ifnull(rec.get("Email"),"").toString().trim().toLowerCase();
phone = ifnull(rec.get("Phone"),"").toString().replaceAll("[^0-9]","");
lastName = ifnull(rec.get("Last_Name"),"").toString().trim().replaceAll("[(),]","");
firstName = ifnull(rec.get("First_Name"),"").toString().trim().replaceAll("[(),]","");
// 照合する条件を「理由」と組で並べる。空の値は比べない
checks = List();
if(email != "")
{
checks.add({"reason":"メール","criteria":"(Email:equals:" + email + ")"});
}
if(phone.length() >= 10)
{
checks.add({"reason":"電話番号","criteria":"(Phone:equals:" + phone + ")"});
}
if(lastName != "" && firstName != "")
{
checks.add({"reason":"姓名","criteria":"((Last_Name:equals:" + lastName + ")and(First_Name:equals:" + firstName + "))"});
}
for each c in checks
{
found = zoho.crm.searchRecords("Contacts",c.get("criteria"));
for each r in found
{
rid = ifnull(r.get("id"),"").toString();
// 自分自身は除く
if(rid != "" && rid != contactId)
{
if(!reasons.contains(c.get("reason")))
{
reasons.add(c.get("reason"));
}
// 候補IDは1行テキストに入れるため、先頭10件までにする
if(!candidateIds.contains(rid) && candidateIds.size() < 10)
{
candidateIds.add(rid);
}
}
}
}
if(reasons.size() == 0)
{
info "重複候補なし: " + contactId;
return;
}
// 統合はしない。フラグと理由と候補IDを残すだけ
upd = Map();
upd.put("Duplicate_Flag",true);
upd.put("Duplicate_Reason",reasons);
upd.put("Duplicate_Candidate_IDs",candidateIds.toString(","));
opt = Map();
opt.put("trigger",List());
res = zoho.crm.updateRecord("Contacts",contactId.toLong(),upd,opt);
info "重複候補あり: " + reasons + " / " + res;
}
ポイントは次のとおりです。
- 関数は統合も削除もしません。 書き込むのは自分自身の3項目だけです。誤検知でも、フラグを外せば元どおりになります
- 空の値と短すぎる電話番号は照合しません。 正規化で桁がそろわなかった電話番号(元の値のまま残したもの)は比べない、という意味もあります
- 検索条件を壊す記号は除いてから照合します。 氏名に括弧やカンマが入っていると検索条件として読めなくなるため、比べるときだけ取り除きます
- 候補の数には上限を置いています。 当社が確認した時点では、
searchRecordsはページを指定しないと1ページ目(初期値で最大200件)だけを返します。印を付ける目的なら1ページ目で足りますが、候補IDの一覧は先頭の分だけになります。1行テキストの項目には文字数の上限もあるため、候補IDは10件までにしています - 更新でワークフローを動かしません。
updateRecordのtriggerを空にして、この関数の書き込みで作成・編集のワークフローがもう一度動かないようにしています - 継続寄付の会員番号による上書き更新は、この関数ではなく取込側で行います。 取込(DataPrepなど)の照合キーに会員番号を指定し、一致すれば更新、なければ新規作成とします
取引先の関数も同じ形で、照合する項目を正規化した法人名に変え、理由を「法人名」にします。
重複フラグが付いたデータはどう確認するか
フラグが付いたデータは、次の流れで確認します。
- 「重複フラグ=オン」の連絡先を一覧できるレポート(またはビュー)を開く
- 候補のIDのデータと並べ、一致した理由と、住所・寄付履歴などほかの項目を見比べる
- 判断して、次のどれかを行う
- 同じ人 → Zohoの標準の統合機能でまとめる。残す値は1件ずつ選ぶ
- 別人 → フラグを外し、「確認済み(別人)」と分かるようにしておく
- どちらかのデータが誤り → 誤っている値を直してからフラグを外す
- 郵送やメール配信の前には、フラグが残っていないことを確かめる
「別人」と確かめた組を記録しておくのも大切です。記録がないと、項目を直すたびに同じ組がまた候補に挙がり、確認の手間が増えていきます。
統合以外に決めておく運用ルール
重複チェックを設計すると、「そもそも何を1人とみなすか」という問いに必ず行き当たります。この案件で決めたこと・論点になったことを挙げます。
メールアドレスを「人の単位」にする
寄付者や法人の担当者は、メールアドレスを基準に管理すると決めました。転職などでメールアドレスが変わった場合は、別人として新しく登録し、前の連絡先にはメモやメール配信停止の印で経緯を残します。1人の連絡先に過去の勤務先のメールを何個も持たせるより、照合の基準がぶれません。
役職宛ての連絡先
関係する施設の中には、施設長・事務局長のように、個人名ではなく役職宛てに郵送するところがありました。こうした連絡先は役職をもとに登録し、氏名が分かったら同じ連絡先の氏名を更新します。担当者が交代したときは、上書きせずに新しい連絡先を作ると決めました。上書きすると、前任者とのやり取りの記録が新しい人のものに見えてしまうおそれがあるためです(理由は当社の考え)。
1人が複数の種類に当てはまるときの二重送付
同じ人が「継続寄付者」と「物品の寄付者」のように複数の種類に当てはまると、種類ごとに配信リストを作ったときに、同じメールが2通届くことがあります。これは重複データではなく、1件の連絡先が複数の条件に当てはまることで起きます。対策は2つ考えられます。
- 配信のたびに、セグメントの検索条件を組み直して1人1通にする
- 「送付済み」の印を項目として持ち、送るたびに印を足していく
取引先の統合は急がない
取引先(法人)は、支援団体・メディア・関係施設など種類が多く、法人名の表記の揺れも大きいため、名前だけで確実に重複を見つけるのは難しいことが分かりました。この案件では、目前の郵送に影響が小さいことから、取引先の統合は後の段階に回しました。将来の照合キーとして、法人番号のように1社に1つ決まる番号を持たせることを検討しています。
法人名を比べる前の正規化(法人格の除去など)は、「名刺の名寄せをZoho CRMで自動化する設計」で詳しく紹介しています。
見込み客との照合は別に決める
見込み客(まだ寄付に至っていない法人など)と、連絡先・取引先との照合は、見込み客の使い方自体が決まっていなかったため、今回の範囲から外しました。名刺の取り込み方や、見込み客から連絡先へ変えるときの規則と一緒に決めます。
ほかの名寄せの記事との違い
当社の記事では、名寄せをいくつかの切り口で扱っています。
- 「顧客データ統合の進め方」:企業向けの営業データを、メール→ドメイン→取引先の順で名寄せする方法
- 「名刺の名寄せをZoho CRMで自動化する設計」:名刺の自動同期で、決めきれないものを「要確認」で止める方法
- 「Zoho CRMで複合ユニークキーを作る方法」:基幹システムのCSVを取り込むときの一意キーの決め方
この記事は、入口ごとに照合キーの強さが違うときに、自動で処理してよい範囲をどう線引きするかに絞っています。
設計のチェックリスト
- 取込元ごとに、照合に使う項目を表にした
- 自動で上書き更新するキーは、「1人に1つ」「あとから変わらない」を取込元に確かめた
- 確かめられていないキーは、暫定で重複フラグの扱いにした
- 比べる前に、全角半角・大文字小文字をそろえ、空の値は比べないようにした
- 重複フラグを、一致した理由ごとに分けた
- フラグ付きのデータを一覧するレポート・ビューを用意した
- 統合・別人・データ修正のどれにするかを、誰がいつ判断するか決めた
- 「別人」と確かめた組を記録する場所を決めた
- メールアドレスが変わった人、役職宛ての連絡先の扱いを決めた
- 複数の種類に当てはまる人への二重送付の防ぎ方を決めた
- 取引先・見込み客の照合を、今回の範囲に入れるかどうか決めた
自動で処理する範囲の線引きを含め、重複の扱いの設計はZoho導入支援・コンサルティングでご相談いただけます。
よくある質問
Zoho CRMの重複データの統合機能(自動マージ)は使ってはいけませんか?
統合の作業そのものは標準の機能を使って構いません。この記事で避けているのは、取込のたびに条件が一致したデータを機械が自動で統合することです。公式ヘルプでは、統合した重複レコードは削除されて元に戻せないとされています。どのデータを統合するかの判断は人が行い、実際の統合作業に標準の機能を使う、という分担にします。
重複フラグが付いたデータは、どのくらいの頻度で確認すればよいですか?
郵送やメール配信など、データを使う前には必ず確認します。それとは別に、取込の頻度に合わせて週1回や月1回など決まった間隔で確認すると、フラグがたまりすぎません。フラグ付きのデータを一覧できるレポートやビューを用意しておくと、確認の手間が減ります。
氏名だけが一致した場合も重複フラグを付けるべきですか?
メールアドレスがない取込元のデータでは、氏名が唯一の手がかりなので付けます。ただし同姓同名の別人は珍しくないため、氏名の一致は最も弱い手がかりとして扱い、住所や電話番号も見て判断します。
法人(取引先)の重複はどう見つければよいですか?
法人名を正規化してから比べるのが基本です。ただ、法人名は「株式会社」の位置や略し方の揺れが大きく、名前だけでは見落としや誤検知が残ります。確実にするなら、法人番号のように1社に1つ決まる番号を取引先に持たせることを検討します。




