CSV Merger

To merge files, drop in any mix of CSV, Excel, JSON and JSONL and get one table back. Stack the rows vertically, or join files side by side on a key column. When the schemas disagree you decide what wins: map any column onto any other, skip what you do not want, and a report names every column that was filled or dropped before you download anything.

The merge is easy. The schemas are the problem.

Concatenating files that agree on their columns is a one-liner anywhere. Real exports do not agree, because they come from different months of a changing system, different tools, or different people:

  • A column was added in March. January and February exports have 8 columns, everything after has 9. Blindly stacking them shifts nothing, but a naive tool either errors out or drops the new column without a word. Here, the union mode keeps it and back-fills blanks, and the report says which files were short.
  • Same column, different spelling. One system writes Email, the next writes email, a third writes EMAIL with a trailing space. Matching is case- and whitespace-insensitive because that is the reality of exports, and the first file's spelling wins in the output.
  • Different column orders. By-name matching does not care where the column sits. If your files genuinely have no headers, switch to by-position and the columns line up by index instead.
  • You need to know what came from where. One tick adds a source_file column carrying the filename, or the workbook sheet name, of every row's origin, which turns twelve monthly exports into a table you can group by month immediately.

Worked example: two exports, one new column

Say jan.csv predates the loyalty program:

id,name,city
1,Ada,London
2,Grace,Boston

and feb.csv gained a column and lost another:

id,name,loyalty_tier
3,Alan,gold

With All columns and the source column on, the merge is:

source_file,id,name,city,loyalty_tier
jan.csv,1,Ada,London,
jan.csv,2,Grace,Boston,
feb.csv,3,Alan,,gold

And the schema differences panel above the preview reads: jan.csv is missing loyalty_tier, feb.csv is missing city. Nothing was guessed and nothing vanished. Switch to Shared columns only and the output narrows to id and name, with the panel now naming city and loyalty_tier as dropped.

What goes in, what comes out

  • In: CSV, TSV and TXT with the delimiter sniffed per file, Excel workbooks where every sheet with data becomes its own source, JSON arrays of objects, and JSON Lines. Mix them freely; a JSON export and a CSV export of the same system merge like any two CSVs.
  • Out: CSV, TSV, a real .xlsx workbook, JSON, JSON Lines, Parquet, a native DuckDB database, a SQLite database or an Arrow file. The JSON output types its values by reading whole columns, so ids that are numbers arrive as numbers, and 007 stays a string instead of becoming James Bond's float.
  • Two directions: Stack rows appends every file's rows into one long table (the vertical merge). Join side by side lines files up on a key column, like a spreadsheet VLOOKUP across whole files, or by plain row order when there is no key (the horizontal merge).
  • Column mapping: when two files spell a column differently, the map button on each file routes any of its columns into any output column, or skips it. Automatic matching handles the rest.
  • Order: rows keep their file order, files keep the order in the list, and the arrows let you reorder them. The first file in the list is the schema authority for by-position matching, the First file's columns mode, and the left side of a join.
  • Onward: Open in Data Explorer hands the merged table to the full editor for joins, filters, pivots, charts and Parquet export.

Frequently Asked Questions

What happens when my files have different columns?

You choose, and the widget shows its work either way. All columns keeps the union and fills the gaps with blanks. Shared columns only keeps the intersection. First file's columns forces everything into the schema of the file at the top of the list. Before you download, a schema differences panel names exactly which file is missing which column and which columns are being dropped, so nothing disappears silently.

Can I mix formats, like two CSVs and an Excel workbook?

Yes. CSV, TSV, TXT, Excel (.xlsx and .xls), JSON arrays and JSON Lines all become tables before merging, so the mix does not matter. A workbook with several data sheets contributes each sheet as its own source, which also makes this the quickest way to merge all sheets of one Excel file into a single table.

How do I know which file each row came from?

Tick Add source_file column and every row carries the name of the file, or workbook sheet, it came from. If your data already has a column called source_file, the new one is renamed rather than overwriting yours.

Does column matching care about capitalisation?

No. Email, email and EMAIL with stray spaces around it are treated as the same column, because that is what exports from different systems actually look like. The output uses the spelling from the first file that had the column.

One file calls it e-mail, the other calls it email. Can I map them together?

Yes. Every file in the list has a map-columns button that opens a panel listing its columns. Point e-mail at email and the values land in one column instead of two half-empty ones. The same panel can skip a column outright, and hand-skipped columns never trigger the dropped-column warning, because you chose it.

Can I join files side by side instead of stacking rows?

Yes, switch Combine to Join side by side. Rows align on a key column present in every file, with three row policies: keep the first file's rows, keep only rows matched in every file, or keep all rows from all files with blanks where a file has no match. Duplicate keys use their first occurrence and are counted in a warning. If your files have no shared key, aligning by row order pastes them together line by line instead.

What if the files have no headers, or the headers are wrong?

Switch matching to By position. Column 1 lines up with column 1, column 2 with column 2, and the first file's header names the output. Files wider than the first get placeholder names for the extra columns in All columns mode, or are trimmed in Shared columns mode.

Do my files leave my computer?

No. Reading, parsing and merging all happen in your tab. There is no upload endpoint, no account and no file counter. The limit is 100 MB per file; past that, the full editor streams files instead of holding them in memory.

Twelve exports, one table

Free, no account, no upload. Drop the files, settle the schema, take the merge.

Back to the merger