Find CSV rows with no matching key

Paste two CSV tables and return the rows from A whose key is absent from B — or B-only / both directions. Match by header name or column index, use composite keys, and keep all unmatched duplicates.

Try:
Anti-join result CSV

About this tool

CSV anti-join is the spreadsheet version of "show me what is missing." Paste two CSV tables, choose the key column, and the tool returns rows from CSV A whose key does not appear in CSV B. That is useful for reconciling exports, finding customers not present in another system, locating inventory codes missing from a reference list, or preparing a cleanup list before a migration.

Use A only for the standard left anti-join. Switch to B only for the reverse check, or Both sides to emit a symmetric difference with a leading _source column that marks whether each unmatched row came from A or B. Keys can be header names (id) or 1-based column indexes (1), and comma-separated keys (first,last) form a composite match. If the key columns have different names in the two CSVs, set the B key separately — matching is by value, not by header.

Duplicate keys in the lookup table do not multiply rows. If A contains two unmatched rows with the same key, both A rows are kept, because they are real rows missing from B. You can choose comma, tab, semicolon, pipe, or any single-character delimiter, and optionally make key matching case-insensitive or trim whitespace around key values.

Worked example

CSV A:

id,name
1,Alice
2,Bob
3,Carol

CSV B:

id,city
2,Berlin
3,Cairo
4,Delhi

Key: id, direction: A only.

Output:

id,name
1,Alice

FAQ

What is an anti-join?

An anti-join returns rows from one table when their key does not exist in another table. It is the opposite of an inner join: instead of keeping matches, it keeps non-matches. In SQL terms, this is similar to LEFT JOIN ... WHERE right.key IS NULL or a NOT EXISTS query.

Can the key column have a different name in CSV B?

Yes. Put the A key in Key column(s) in A and the B key in Key column(s) in B. For example, A might use customer_id while B uses id. The tool compares the key values, so the header names do not need to match. Leave the B key blank when both files use the same key name or index.

How are duplicate keys handled?

The comparison side is treated as a key set, so duplicate keys in B do not multiply or otherwise affect A's output. On the output side, every unmatched row is kept. If CSV A has two rows with key x and x is absent from B, both rows appear in the result.

Can I compare on more than one column?

Yes. Use a comma-separated list such as first,last or 1,3. The same number of key columns must be supplied for CSV B. A row matches only when all key parts match after the case-sensitivity and trim settings are applied.

Does the tool upload my CSV data?

No. The anti-join runs in WebAssembly inside your browser tab. Your pasted CSV text is processed locally and is not sent to a server.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool csv-anti-join "id,name
1,Alice
2,Bob
3,Carol" 'b=id,city
2,Berlin
3,Cairo
4,Delhi' 'key=id'

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/csv-anti-join/?a=id%2Cname%0A1%2CAlice%0A2%2CBob%0A3%2CCarol&b=id%2Ccity%0A2%2CBerlin%0A3%2CCairo%0A4%2CDelhi&key=id&key_b=id&direction=a-only&delimiter=%2C&case_sensitive=true&trim_keys=true

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.