Skip to the tool
ViewCSV
Files stay on your device

Merge CSV files: stack rows or join by column

2 files
  1. customers.csv8 rows · customer_id, name, country, segment
  2. invoices.csv10 rows · customer_id, invoice_no, total, paid
How to combine
Result
Result
#customer_idnamecountrysegmentinvoice_nototalpaid
100301Liam JohnsonUnited Statesbusiness···
200302Olivia BrownUnited Stateseducation···
300303Ethan WilsonUnited Stateseducation···
400304Sophia GarciaUnited Statesbusiness···
500305Olivia SmithUnited Statesbusiness···
600306Liam TaylorUnited Stateseducation···
700307Sophia TaylorUnited Stateseducation···
800308Sophia GarciaUnited Statesbusiness···
900308···INV-2400352.82false
1000309···INV-240194.00true
1100307···INV-2402498.24true
1200305···INV-2403266.43true
1300308···INV-240421.08true
1400309···INV-2405640.16false
1500308···INV-2406850.75true
1600309···INV-2407261.68true
1700303···INV-2408796.91true
1800303···INV-2409776.95true

18 rows · 7 columns

To merge CSV files, add two or more files and choose how to combine them. Append stacks every file’s rows into one table, matching columns by header name, so a column that only some files have is kept and left empty elsewhere; this is what most people mean by merging monthly or regional exports. Join puts two files side by side on one or more key columns, like a spreadsheet lookup, and tells you how many rows matched, which keys repeat and how many extra rows that created. The merged table updates as you change the options, and the files are merged in your browser, never uploaded.

How to merge CSV files

  1. Add the files. Each one is read with its delimiter and encoding detected and its first row used as the header. The list shows each file's row count and first columns; move files up or down to set the order.
  2. Choose append to put the rows of every file one after another, or join to match the rows of the first two files on a key.
  3. Check the preview and the notes above it, then download the result as CSV or open it in the CSV editor to keep working.

Rows keep the order of the file list: all rows of the first file, then all rows of the second, and so on. To merge many monthly exports, add them all at once and turn on the source column so every row still says which file it came from.

Append: stacking files with different columns

Append has three ways to line up columns. Pick the one that matches how your files differ.

Match by header name (default)The result has every header from every file, in order of first appearance. A row from a file that lacks a column gets an empty value there. Names must match exactly: SKU and sku become two columns.
Require identical headersStops with an error naming the first file whose headers differ in name, count or order. Use it when every file should come from the same export and a renamed column means something went wrong.
Match by positionColumn 1 goes under column 1, and so on. The headers come from the file with the most columns; shorter files get empty values at the end. Only use it when the files have no usable header or the same layout under different names.
Add a source columnAdds a last column, named source_file unless you change it, holding each row's file name. The name must not already be a header.
Remove duplicate rowsAfter stacking, drops every row identical to an earlier one and reports how many were removed. The first copy is kept. Values must match exactly, including case and spaces; the source column is ignored, so the same row in two files counts as a duplicate.

Matching by position puts values under the wrong header when one file has an extra or reordered column: in the example below, April's qty would land under name. Match by header name avoids this whenever the files have headers.

Join: combining two files on a key

Join uses the first two files in the list as left and right. Choose one or more key column pairs; each pair can have different names, such as customer_id on the left and id on the right. With several pairs, a row matches only when every pair matches.

Left join (default)Every left row, with right columns filled where the key matched and empty where it didn't.
Inner joinOnly left rows whose key is found in the right file.
Right joinEvery right row: matched rows in left-file order, followed by right rows that matched nothing.
Full joinEvery row from both files: the left join result followed by right rows that matched nothing.
Ignore case and surrounding spaces in keys C02 matches c02. The left file's key text is the one written to the result.

The result has all left columns, then the right file's columns except its key columns. A right column whose name is already used gets (2) added, for example total (2), and the notes list the renamed columns. For a right row that matched nothing, its key is written into the left key column and the other left columns stay empty.

If a key appears more than once in the right file, each matching left row is repeated once per match. The notes count matched, left-only and right-only rows, repeated keys on each side and the extra rows created, so a lookup that should be one-to-one shows immediately when it isn't.

Values, headers and mixed delimiters

  • Values are text and stay exactly as written, so 00123 keeps its leading zeros. Keys are compared as text too: 00123 and 123 do not match, even with case and spaces ignored.
  • Quoted delimiters, quotes and line breaks inside a value are read per RFC 4180 and quoted again where needed in the download.
  • Within one file, a blank header becomes Column 3 and a repeated one becomes name (2). Those generated names take part in matching by header name like any other.
  • Files may use different delimiters and encodings; each is detected separately. The download is comma-delimited, and its line endings and encoding follow the first file in the list. Encodings a browser cannot write, such as Shift_JIS, are saved as UTF-8.

Merge and join problems

  • Columns appear twice with slightly different names. The files spell a header differently (Email and email, or a trailing space). Rename one with Rename and reorder CSV columns before merging, or use match by position if the layouts are identical.
  • A join matched almost nothing. Check that keys are written the same way in both files: leading zeros, prefixes and spaces all count. Turn on ignore case and surrounding spaces, or trim the column first with Clean CSV data.
  • The join has more rows than the left file. The right file repeats a key; the notes show how many keys repeat and how many extra rows they created. Remove the duplicates or choose a more specific key pair.
  • The merged table exceeds the browser limit. The result can have at most 100,000 rows and 2 million cells. Filter the inputs first, or merge fewer files at a time.

Merge limits and privacy

Each file can be up to 25 MB, 100,000 rows, 250 columns and 2 million cells, and the merged or joined result is held to the same 100,000 rows and 2 million cells. Merging is not streamed: every file is loaded into memory.

Files are read in a background worker in this tab and merged in your browser. They are never sent to a server. To find what changed between two versions of a file rather than combine them, use Compare CSV files; to cut one file into several, use Split CSV files.

Example: appending two inventory files with different columns

Two inventory exports with different columns, appended by header name with the source column turned on. name and warehouse exist in only one file, so the other file's rows are empty there, and the SKUs keep their leading zeros.

CSV
march.csv
sku,name,qty
00123,"Desk lamp, brass",4
00456,Shelf,2

april.csv
sku,qty,warehouse
00789,10,North
00456,2,
merged.csv
sku,name,qty,warehouse,source_file
00123,"Desk lamp, brass",4,,march.csv
00456,Shelf,2,,march.csv
00789,,10,North,april.csv
00456,,2,,april.csv

Questions and answers

Can I join more than two files?

Not in one step. Join uses the first two files in the list. Download or open the result, then join it with the next file. Append has no such limit and stacks every file you add.

Does removing duplicate rows compare only a key column?

No. A row is removed only when every value matches an earlier row exactly. To keep one row per ID, run the result through Clean CSV data and remove duplicates by key column there.

Why did match by position put values under the wrong header?

Position mode ignores header names and takes the headers from the file with the most columns. If one file has a column the others lack, every later value shifts. Switch to match by header name.

Standards and references