CSV 結合・マージ
データ変換
読み込み中
ツールを読み込んでいます
ツールのコードは開いたときにのみ読み込まれます。
このツールの処理はすべてブラウザー内で行われ、入力内容はサーバーへ送信されません。
このツールについて
注文データに顧客名を追加したり、地域別の参照表を組み合わせたりするためのローカル結合ツールです。左右で名前の異なるキー列を対応付け、左結合・内部結合・完全外部結合を選びます。必要な出力列だけを選択でき、同名列には必ず left. または right. が付くため、出所を区別できます。重複キーは初期設定ではエラーになります。意図した一対多・多対多の関係を扱う場合は、展開を明示的に選び、事前確認の件数を確認して組み合わせの生成を承認してください。解析・結合計画・書き出しは、ブラウザー内の使い捨て Worker で実行します。
主な用途
- 注文表の customer_id を顧客表の id に対応付け、左結合で order_id、total、name、tier を取り出す。
- region と customer_id の複合キーで地域別データを結合し、右表の異なるキー列名にも対応する。
- 完全外部結合で一致した行と未一致の行を確認し、必要な列を元の左右データ行番号とともに保存する。
使い方
- 1.左右に CSV を貼り付けるかローカルファイルを選び、それぞれの区切り文字、ヘッダーの有無、文字コードを指定します。区切り文字はカンマ・セミコロン・タブ・縦棒、ファイルの文字コードは UTF-8・UTF-16LE・UTF-16BE に対応します。列を確認したら、左キーと右キーの対応を一つ以上、同じ組の順序で設定します。列名は完全一致で指定し、ヘッダーなしの場合は column1、column2 などの生成名を使います。結合方法と左右の出力列を選びます。
- 2.通常は文字列の完全一致を使い、必要な場合だけキーの前後空白除去や大文字・小文字を無視する設定を有効にします。空のキー要素は、拒否・空同士を一致・常に未一致から選択します。事前確認で重複グループ、一致・未一致の元データ行数、出力行数、セル数、シリアライズ後のバイト数を確認します。初期設定では、正当な参照関係の「多」側であっても重複キーを拒否します。繰り返すキーを残す場合は直積展開を選び、事前確認が通った現在の内容を承認してから結合します。入力や設定の変更により、承認と以前の結果は無効になります。
- 3.ページ分けされた結果で左右の元データ行番号を確認します。左結合は左の全行、内部結合は一致する行の組、完全外部結合はさらに未一致の右行を残します。JSON では元の文字列と欠けた側を示す null を保持します。CSV は五つの出所情報列に続いて、接頭辞付きの選択列を出力します。表計算ソフトで確認する場合は数式対策を有効にし、生の CSV はリスクと読込先を確認したうえで選んでください。ページ分けや表示の省略はダウンロード内容を減らしません。
実行して確認できる CSV 結合例
左結合で注文に顧客情報を追加
{
"left": "order_id,customer_id,total\nA100,001,12.50\nA101,002,0\nA102,009,7",
"right": "id,name,tier\n001,Alice,gold\n002,Bob,silver\n003,Chika,bronze",
"leftOptions": {
"delimiter": ",",
"header": true
},
"rightOptions": {
"delimiter": ",",
"header": true
},
"joinOptions": {
"kind": "left",
"keys": [
{
"left": "customer_id",
"right": "id"
}
],
"leftColumns": [
"order_id",
"total"
],
"rightColumns": [
"name",
"tier"
],
"trim": false,
"ignoreCase": false,
"emptyKeys": "reject",
"duplicates": "reject"
}
}{
"headers": [
"left.order_id",
"left.total",
"right.name",
"right.tier"
],
"summary": {
"matched": 2,
"leftOnly": 1,
"rightOnly": 0,
"total": 3
},
"rows": [
{
"kind": "matched",
"leftRow": 1,
"rightRow": 1,
"values": [
"A100",
"12.50",
"Alice",
"gold"
]
},
{
"kind": "matched",
"leftRow": 2,
"rightRow": 2,
"values": [
"A101",
"0",
"Bob",
"silver"
]
},
{
"kind": "left-only",
"leftRow": 3,
"rightRow": null,
"values": [
"A102",
"7",
null,
null
]
}
]
}customer_id を id に対応付け、選択した注文・顧客フィールドだけを残します。A100 と A101 は一致し、A102 は顧客が見つからないため右側の値が null になります。文字列 12.50 はそのままです。
内部結合で一致した注文だけを保持
{
"left": "order_id,customer_id,total\nA100,001,12.50\nA101,002,0\nA102,009,7",
"right": "id,name,tier\n001,Alice,gold\n002,Bob,silver\n003,Chika,bronze",
"leftOptions": {
"delimiter": ",",
"header": true
},
"rightOptions": {
"delimiter": ",",
"header": true
},
"joinOptions": {
"kind": "inner",
"keys": [
{
"left": "customer_id",
"right": "id"
}
],
"leftColumns": [
"order_id",
"total"
],
"rightColumns": [
"name",
"tier"
],
"trim": false,
"ignoreCase": false,
"emptyKeys": "reject",
"duplicates": "reject"
}
}{
"headers": [
"left.order_id",
"left.total",
"right.name",
"right.tier"
],
"summary": {
"matched": 2,
"leftOnly": 0,
"rightOnly": 0,
"total": 2
},
"rows": [
{
"kind": "matched",
"leftRow": 1,
"rightRow": 1,
"values": [
"A100",
"12.50",
"Alice",
"gold"
]
},
{
"kind": "matched",
"leftRow": 2,
"rightRow": 2,
"values": [
"A101",
"0",
"Bob",
"silver"
]
}
]
}同じ入力でも、内部結合では A100 と A101 だけになります。未一致の注文 A102 と、注文のない顧客 Chika は含みません。
完全外部結合で未一致の注文と顧客も保持
{
"left": "order_id,customer_id,total\nA100,001,12.50\nA101,002,0\nA102,009,7",
"right": "id,name,tier\n001,Alice,gold\n002,Bob,silver\n003,Chika,bronze",
"leftOptions": {
"delimiter": ",",
"header": true
},
"rightOptions": {
"delimiter": ",",
"header": true
},
"joinOptions": {
"kind": "full",
"keys": [
{
"left": "customer_id",
"right": "id"
}
],
"leftColumns": [
"order_id",
"total"
],
"rightColumns": [
"name",
"tier"
],
"trim": false,
"ignoreCase": false,
"emptyKeys": "reject",
"duplicates": "reject"
}
}{
"headers": [
"left.order_id",
"left.total",
"right.name",
"right.tier"
],
"summary": {
"matched": 2,
"leftOnly": 1,
"rightOnly": 1,
"total": 4
},
"rows": [
{
"kind": "matched",
"leftRow": 1,
"rightRow": 1,
"values": [
"A100",
"12.50",
"Alice",
"gold"
]
},
{
"kind": "matched",
"leftRow": 2,
"rightRow": 2,
"values": [
"A101",
"0",
"Bob",
"silver"
]
},
{
"kind": "left-only",
"leftRow": 3,
"rightRow": null,
"values": [
"A102",
"7",
null,
null
]
},
{
"kind": "right-only",
"leftRow": null,
"rightRow": 3,
"values": [
null,
null,
"Chika",
"bronze"
]
}
]
}完全外部結合では A102 を残し、左側の全行の後に Chika を追加します。null の元データ行番号と値によって、欠けた側を空文字列と区別できます。
地域と顧客番号の複合キーを対応付ける
{
"left": "region,customer_id,order_id\nNorth,007,A201\nSouth,007,A202",
"right": "territory,id,name\nSouth,007,Minami\nNorth,007,Kita",
"leftOptions": {
"delimiter": ",",
"header": true
},
"rightOptions": {
"delimiter": ",",
"header": true
},
"joinOptions": {
"kind": "left",
"keys": [
{
"left": "region",
"right": "territory"
},
{
"left": "customer_id",
"right": "id"
}
],
"leftColumns": [
"region",
"customer_id",
"order_id"
],
"rightColumns": [
"name"
],
"trim": false,
"ignoreCase": false,
"emptyKeys": "reject",
"duplicates": "reject"
}
}{
"headers": [
"left.region",
"left.customer_id",
"left.order_id",
"right.name"
],
"summary": {
"matched": 2,
"leftOnly": 0,
"rightOnly": 0,
"total": 2
},
"rows": [
{
"kind": "matched",
"leftRow": 1,
"rightRow": 2,
"values": [
"North",
"007",
"A201",
"Kita"
]
},
{
"kind": "matched",
"leftRow": 2,
"rightRow": 1,
"values": [
"South",
"007",
"A202",
"Minami"
]
}
]
}顧客番号 007 が二つの地域に存在します。region と territory、customer_id と id を対応付けると、それぞれ別の組として識別します。右表の並び方が違っても左表の出力順は変わりません。
先頭ゼロのあるキーを区別
{
"left": "customer_id,code\n001,007\n1,7",
"right": "id,name\n1,Alice",
"leftOptions": {
"delimiter": ",",
"header": true
},
"rightOptions": {
"delimiter": ",",
"header": true
},
"joinOptions": {
"kind": "left",
"keys": [
{
"left": "customer_id",
"right": "id"
}
],
"leftColumns": [
"customer_id",
"code"
],
"rightColumns": [
"id",
"name"
],
"trim": false,
"ignoreCase": false,
"emptyKeys": "reject",
"duplicates": "reject"
}
}{
"headers": [
"left.customer_id",
"left.code",
"right.id",
"right.name"
],
"summary": {
"matched": 1,
"leftOnly": 1,
"rightOnly": 0,
"total": 2
},
"rows": [
{
"kind": "left-only",
"leftRow": 1,
"rightRow": null,
"values": [
"001",
"007",
null,
null
]
},
{
"kind": "matched",
"leftRow": 2,
"rightRow": 1,
"values": [
"1",
"7",
"1",
"Alice"
]
}
]
}キー 001 は 1 と一致しません。数値変換で先頭ゼロを消すことはなく、選択した code の 007 も文字列のまま残します。
キーだけを正規化し、出力文字列を保持
{
"left": "customer_id,status\n A , Paid ",
"right": "id,name\na,ALICE",
"leftOptions": {
"delimiter": ",",
"header": true
},
"rightOptions": {
"delimiter": ",",
"header": true
},
"joinOptions": {
"kind": "left",
"keys": [
{
"left": "customer_id",
"right": "id"
}
],
"leftColumns": [
"customer_id",
"status"
],
"rightColumns": [
"id",
"name"
],
"trim": true,
"ignoreCase": true,
"emptyKeys": "reject",
"duplicates": "reject"
}
}{
"headers": [
"left.customer_id",
"left.status",
"right.id",
"right.name"
],
"summary": {
"matched": 1,
"leftOnly": 0,
"rightOnly": 0,
"total": 1
},
"rows": [
{
"kind": "matched",
"leftRow": 1,
"rightRow": 1,
"values": [
" A ",
" Paid ",
"a",
"ALICE"
]
}
]
}前後空白の除去と大文字・小文字の無視によって A と a は一致しますが、元のキー " A "、状態 " Paid "、名前 "ALICE" は書き換えずに出力します。
初期設定では重複する顧客キーを拒否
{
"left": "customer_id,order_id\n001,A1\n001,A2",
"right": "id,name\n001,Alice",
"leftOptions": {
"delimiter": ",",
"header": true
},
"rightOptions": {
"delimiter": ",",
"header": true
},
"joinOptions": {
"kind": "left",
"keys": [
{
"left": "customer_id",
"right": "id"
}
],
"leftColumns": [
"order_id"
],
"rightColumns": [
"name"
],
"trim": false,
"ignoreCase": false,
"emptyKeys": "reject",
"duplicates": "reject"
}
}{
"error": "duplicateKey"
}左表には顧客 001 の注文が二つあります。右側の参照キーが一意でも、初期設定では左の重複キーを拒否します。両方の注文を残すなら、展開を明示的に選んでください。
二対二の関係を明示的に展開
{
"left": "customer_id,order_id\n001,A1\n001,A2",
"right": "id,contact\n001,home\n001,work",
"leftOptions": {
"delimiter": ",",
"header": true
},
"rightOptions": {
"delimiter": ",",
"header": true
},
"joinOptions": {
"kind": "left",
"keys": [
{
"left": "customer_id",
"right": "id"
}
],
"leftColumns": [
"order_id"
],
"rightColumns": [
"contact"
],
"trim": false,
"ignoreCase": false,
"emptyKeys": "reject",
"duplicates": "expand"
},
"approveExpansion": true
}{
"headers": [
"left.order_id",
"right.contact"
],
"summary": {
"matched": 4,
"leftOnly": 0,
"rightOnly": 0,
"total": 4
},
"rows": [
{
"kind": "matched",
"leftRow": 1,
"rightRow": 1,
"values": [
"A1",
"home"
]
},
{
"kind": "matched",
"leftRow": 1,
"rightRow": 2,
"values": [
"A1",
"work"
]
},
{
"kind": "matched",
"leftRow": 2,
"rightRow": 1,
"values": [
"A2",
"home"
]
},
{
"kind": "matched",
"leftRow": 2,
"rightRow": 2,
"values": [
"A2",
"work"
]
}
]
}duplicates を expand にし、通過した事前確認を明示的に承認すると、二つの注文と二つの連絡先から四組を生成します。左の注文順を優先し、各注文の中では右の連絡先順を保ちます。
欠損・空文字列・文字列 null を区別
{
"left": "customer_id,order_id\n1,A1\n2,A2\n3,A3",
"right": "id,note\n1,\n3,null",
"leftOptions": {
"delimiter": ",",
"header": true
},
"rightOptions": {
"delimiter": ",",
"header": true
},
"joinOptions": {
"kind": "left",
"keys": [
{
"left": "customer_id",
"right": "id"
}
],
"leftColumns": [
"order_id"
],
"rightColumns": [
"note"
],
"trim": false,
"ignoreCase": false,
"emptyKeys": "reject",
"duplicates": "reject"
}
}{
"headers": [
"left.order_id",
"right.note"
],
"summary": {
"matched": 2,
"leftOnly": 1,
"rightOnly": 0,
"total": 3
},
"rows": [
{
"kind": "matched",
"leftRow": 1,
"rightRow": 1,
"values": [
"A1",
""
]
},
{
"kind": "left-only",
"leftRow": 2,
"rightRow": null,
"values": [
"A2",
null
]
},
{
"kind": "matched",
"leftRow": 3,
"rightRow": 2,
"values": [
"A3",
"null"
]
}
]
}A1 には存在する空のメモ、A2 には対応する顧客がなく、A3 には四文字の null というメモがあります。JSON はそれぞれ ""、null、"null" として、元データ行番号とともに保持します。
区切り文字が異なるヘッダーなし表を結合
{
"left": "001;A1\n002;A2",
"right": "001|Alice\n003|Chika",
"leftOptions": {
"delimiter": ";",
"header": false
},
"rightOptions": {
"delimiter": "|",
"header": false
},
"joinOptions": {
"kind": "full",
"keys": [
{
"left": "column1",
"right": "column1"
}
],
"leftColumns": [
"column1",
"column2"
],
"rightColumns": [
"column2"
],
"trim": false,
"ignoreCase": false,
"emptyKeys": "reject",
"duplicates": "reject"
}
}{
"headers": [
"left.column1",
"left.column2",
"right.column2"
],
"summary": {
"matched": 1,
"leftOnly": 1,
"rightOnly": 1,
"total": 3
},
"rows": [
{
"kind": "matched",
"leftRow": 1,
"rightRow": 1,
"values": [
"001",
"A1",
"Alice"
]
},
{
"kind": "left-only",
"leftRow": 2,
"rightRow": null,
"values": [
"002",
"A2",
null
]
},
{
"kind": "right-only",
"leftRow": null,
"rightRow": 2,
"values": [
null,
null,
"Chika"
]
}
]
}左はセミコロン、右は縦棒を指定し、両方ともヘッダーなしにします。生成された column1 同士を対応付け、必要な位置の列を出力します。接頭辞で出所を区別します。
空のキー要素を常に未一致にする
{
"left": "customer_id,order_id\n,A1",
"right": "id,name\n,Alice",
"leftOptions": {
"delimiter": ",",
"header": true
},
"rightOptions": {
"delimiter": ",",
"header": true
},
"joinOptions": {
"kind": "full",
"keys": [
{
"left": "customer_id",
"right": "id"
}
],
"leftColumns": [
"order_id"
],
"rightColumns": [
"name"
],
"trim": false,
"ignoreCase": false,
"emptyKeys": "never-match",
"duplicates": "reject"
}
}{
"headers": [
"left.order_id",
"right.name"
],
"summary": {
"matched": 0,
"leftOnly": 1,
"rightOnly": 1,
"total": 2
},
"rows": [
{
"kind": "left-only",
"leftRow": 1,
"rightRow": null,
"values": [
"A1",
null
]
},
{
"kind": "right-only",
"leftRow": null,
"rightRow": 1,
"values": [
null,
"Alice"
]
}
]
}never-match を選ぶと、両方のキーが空でも一致しません。完全外部結合では left-only の行と right-only の行を一つずつ出力します。
空のキー要素同士の一致を許可する
{
"left": "customer_id,order_id\n,A1",
"right": "id,name\n,Alice",
"leftOptions": {
"delimiter": ",",
"header": true
},
"rightOptions": {
"delimiter": ",",
"header": true
},
"joinOptions": {
"kind": "left",
"keys": [
{
"left": "customer_id",
"right": "id"
}
],
"leftColumns": [
"order_id"
],
"rightColumns": [
"name"
],
"trim": false,
"ignoreCase": false,
"emptyKeys": "allow",
"duplicates": "reject"
}
}{
"headers": [
"left.order_id",
"right.name"
],
"summary": {
"matched": 1,
"leftOnly": 0,
"rightOnly": 0,
"total": 1
},
"rows": [
{
"kind": "matched",
"leftRow": 1,
"rightRow": 1,
"values": [
"A1",
"Alice"
]
}
]
}allow を選ぶと、二つの空文字列キーを同じものとして扱います。重複検出や展開上限は無効にならず、空キーの意味だけを明示的に変更します。
CSV 結合で起こりやすい間違い
- 顧客番号が地域内だけで一意なのに customer_id だけをキーにする。region と territory の対応も追加してください。
- 顧客が見つからない注文も必要なのに、内部結合を選ぶ。
- 重複キーでも一件だけを取得すると思い込む、または m × n の件数を確認せず展開する。
- 空白除去や大文字・小文字の無視で、別々だったキーが一致することを見落とす。
- 001 と 1 を同じ番号と見なす、または CSV が表計算ソフトに先頭ゼロの保持を強制すると考える。
- 出所情報列を削除してから、欠けた側の空欄を元から空だったセルと解釈する。
- 信頼できない生の CSV を表計算ソフトで開く、または内容を確認せず保存した結果を共有する。
制限と注意事項
- 各入力はファイル自体と復号後の UTF-8 テキストがそれぞれ 2 MiB 以下、データ 10,000 行、128 列、200,000 セル以下です。出力上限は 50,000 行、各行の五つの CSV 出所情報列を含めて 500,000 セル、シリアライズ後の JSON と数式対策付き CSV がそれぞれ 12 MiB です。事前確認では結合結果の行を構築する前に件数と書き出しサイズを計算し、超過時は切り捨てずに停止します。Worker のキャンセルと実行期限は設けていますが、厳密なメモリー隔離ではありません。大きな入力は共通キーの区分で分割するか、ローカルのデータベースを使用してください。
- 値は文字列のまま扱います。001 と 1 は別のキーで、1.0 を 1 に変換しません。前後の空白除去と小文字化は結合キーだけに適用され、出力値やヘッダー名は変更しません。あいまい一致、数値・日付変換、Unicode 正規化、ロケール依存の照合には対応しません。複合キーは区切り文字で単純連結せず、要素の組として識別します。正規化後の要素が一つでも空なら、指定した空キーの方針を適用します。重複検出にも同じ正規化を使うため、設定によって衝突が生じることがあります。「常に未一致」の空キーは共通の空キーグループにはなりません。
- 左右いずれかで完全なキーが重複すると、未一致の重複グループであっても初期設定では結合を止めます。最初や最後の行を勝手に選びません。明示的な展開では同じキーの全組み合わせを作り、左が二行、右が三行なら六行になります。左が複数行で右が一行の場合も、展開の選択と承認が必要です。件数は選択した結合方法に対応し、matched は出力される行の組数なので、一致した元データ行数を上回る場合があります。左の入力順、各左行に対応する右の入力順、完全外部結合の未一致右行の順に出力します。集計、重複排除、あいまい結合、SQL 実行は行いません。
- 選択列の名前は必ず left.<元の列名> または right.<元の列名> になります。同名列やキー列を左右両方から選べば、両方を保持します。JSON では欠けた側の値を null、存在する空セルを ""、文字列の null を "null" とし、行の種類と 1 から始まる nullable な leftRow/rightRow も保存します。CSV は欠けた値を空欄にし、_join_kind、_left_row、_right_row、_left_present、_right_present で出所の有無を区別します。数式対策は危険なフィールドの先頭にアポストロフィーを付けるため、書き出す文字列が変わります。生の CSV は数式として動く可能性があり、表計算ソフトが ID を変換したり、保存後の再読込で対策を失わせたりすることもあります。正確な文字列の受け渡しには JSON を推奨しますが、元ファイルの引用符や改行バイトは復元しません。
- ファイルは選択した対応文字コードで厳密に復号し、BOM もその指定と一致する必要があります。GBK や Shift_JIS は事前に変換してください。不正な引用符、行の列数不一致、空のヘッダー、完全に同名のヘッダーは拒否し、ヘッダーを自動でトリミング・改名しません。引用符内の区切り文字、二重化した引用符、複数行のフィールドは扱えます。出所の行番号はデータ行を 1 から数え、構文エラーはヘッダーを含む CSV レコード番号で示すため、引用符内の物理行とは異なります。このツールは入力をアップロード・永続保存しません。セルは文字列として表示します。保存ファイルには私的な情報が含まれ得るうえ、ページの管理外になります。プレビューは 1 ページ 25 行、選択したデータ列の先頭 12 列を表示し、長いヘッダーや値を省略します。書き出しには選択した全フィールドを含みます。
よくある質問
注文と顧客の結合では、どの方式を選べばよいですか?
注文を左側に置き、customer_id を右の id に対応付けます。左結合は顧客が見つからない注文も残し、JSON の顧客フィールドを null にします。内部結合はその注文を除外し、完全外部結合は注文のない顧客も追加します。複数の注文が同じ customer_id を持つ場合、初期設定の重複エラーは意図した動作です。展開を選び、多対一の参照を意図しているなら顧客側のキーが一意であることを確認し、予測結果を承認してください。
列名が異なる場合や複合キーはどう設定しますか?
キー要素ごとに対応を追加します。たとえば left.region と right.territory、left.customer_id と right.id を対応付けます。対応順に作った要素の組を比較するので、左右の列名は同じでなくてもかまいません。ただし指定名はそれぞれの表に存在する正確な列名である必要があります。先頭のゼロも区別します。元のキー文字列を確認したい場合は、左右のキー列を両方とも出力対象にします。
展開前に事前確認と承認が必要なのはなぜですか?
重複キーは予想以上の行数を生むことがあります。あるキーが左に m 回、右に n 回あれば、展開後は m × n 組です。事前確認では、結果の行を構築する前に重複、元データの件数、この処理範囲における正確な書き出し予定サイズを示します。上限内であることは、意図した関係であることの保証にはなりません。承認は現在の入力と設定だけに適用され、変更後は再確認・再承認が必要です。
未一致の値と空文字列を区別できますか?
はい。JSON では欠けた側の値が null、存在する空欄が ""、null という文字列が "null" になります。各行の種類と元データ行番号も保存します。CSV 自体には null 型がないため、欠けた値を空欄にし、_left_present と _right_present のフラグおよび行番号を併記します。CSV を確認する際は出所情報列を残してください。数式対策付き CSV は数式のような文字列を変える場合があるため、解析後の正確な文字列が必要なら JSON を使います。