Compare CSV exports by identifier, without mistaking a sort for a change

Use a fictional inventory to compare two CSV exports by a composite key. Reproduce exact row and cell differences, diagnose duplicate keys and save a local report.

The short answer

Match records by a stable identifier before comparing their values. In the CSV key comparator, a row moving to another position is not an edit. A changed quantity is. A key present only in the second export is added; a key present only in the first is removed.

Choose the question before the tool

Suppose two inventory exports were sorted differently. Comparing their raw lines can make unchanged stock look different. The keyed comparison asks: for the same item in the same warehouse, which cells changed? It does not determine why they changed, whether a sale occurred, or which export is authoritative. Confirm the export dates and scope yourself before drawing conclusions.

A small, entirely fictional inventory

The identifiers below are text. Keep 001 exactly as written. The English header names and fictional warehouse names are deliberate so that every language version of this example produces the same report.

Before

sku,warehouse,quantity,note
001,North,10,"Blue, small"
002,North,5,Keep
003,South,2,Retire

After

sku,warehouse,quantity,note
002,North,5,Keep
001,North,12,"Blue, small"
004,South,3,New

Reproduce the result

  1. Open the comparator. The fictional-example button replaces both current inputs and runs this example. To do it manually, paste the two blocks into Before and After.
  2. Select comma as the delimiter for both. The comma inside "Blue, small" belongs to the note, not a new column.
  3. Read the columns, then select sku and warehouse as the identifier columns.
  4. Compare the rows and open the changed-row detail.

The exact totals are 1 added, 1 removed, 1 changed, 1 unchanged, and 1 changed cell. Both inputs have three data rows.

  • ["004","South"] is added with quantity "3".
  • ["003","South"] is removed; its old quantity was "2".
  • ["001","North"] changes only in quantity, from "10" to "12".
  • ["002","North"] is unchanged, despite moving up a row.

Why use a composite key?

In this tiny sample, sku alone also happens to be unique. Real exports may repeat the same SKU in several warehouses. Add the line 001,South,7,Other to the end of both samples: selecting only sku now causes a duplicate-key error. Selecting sku plus warehouse works and produces two unchanged rows instead of one. The other totals stay the same. A composite key is a tuple, not a concatenated label, so delimiter-like characters inside components do not create false matches.

Interpret exact strings carefully

The tool does not trim spaces, fold letter case, infer dates or convert numbers. 001 differs from 1; 10 differs from 10.0. Empty text differs from a space. All key components must contain something other than whitespace, and each complete key must be unique within its export. Changing a key is reported as removal plus addition, because the tool has no other proof of identity.

Both files need exactly the same unique, nonblank header names. Column order may differ; added or renamed columns stop the comparison. Missing fields, blank records and malformed quoting are rejected. A final newline is accepted. Double quotes inside a quoted field must be doubled; quoted line breaks remain part of that cell.

Keep the report useful and private

The preview shows at most 100 differing rows and 500 cells, with long values shortened. JSON and plain-text downloads contain every difference in the accepted inputs. Values are JSON-quoted so empty strings, tabs and line breaks remain distinguishable. Record 1 is the header; a quoted newline does not increment the record number. Report field names are stable English labels even when the interface is translated.

Select UTF-8 files of at most 2,000,000 bytes each, or paste up to 2,000,000 UTF-16 code units per input. Each input is also limited to 20,000 data rows, 200 columns and 250,000 cells including the header. There is no encoding detection, fuzzy match or automatic schema merge. Use a smaller, consistently scoped export when a limit is reached.

The comparator keeps inputs in page memory, makes no network requests and writes no browser storage. The website itself still loads code and assets; optional site analytics may run with consent. Clear removes the current inputs and results and cancels a pending read. It does not delete source files or downloaded reports, which may contain private values. No CSV report is produced; do not later paste untrusted values into a spreadsheet without assessing formula risks.

Continue with the right view

Use the CSV explorer to inspect one export. Use the text and JSON comparator when line order or JSON structure is the question. Return to the keyed CSV comparison when stable record identity matters.