CSV inner join
csv-inner-join · version 1.0.0 · CSV & tables · free, no key needed
Inner join two CSV documents on exact named key columns.
Use when you need to: csv inner join · inner join csv · join csv documents on keys.
Supported
- csv inner join
- inner join csv
- join csv documents on keys
Not supported
- outer join
- left join
- fuzzy keys
- numeric keys
- read files
- fetch urls
Behavior
- left and right are complete CSV documents whose first records are headers.
- Empty documents without headers are rejected; header-only documents yield a header-only join.
- keys names unique headers present on both sides; join equality uses those exact cell strings with no coercion.
- Output columns are the keys in listed order, then leftover left columns in left header order, then leftover right columns in right header order.
- Non-key headers that appear on both sides are renamed with left_suffix and right_suffix; keys are never suffixed. Remaining collisions throw.
- Each left row is concatenated with every matching right row. Output follows left row order, then matching right row order. Unmatched left rows and right-only keys are omitted.
- A key tuple with more than 64 rows on either side is rejected even when that key would not appear in the output.
- Output data rows cannot exceed the CSV row limit. The first output header must not begin with U+FEFF.
Input
left(string, required): max length 256000right(string, required): max length 256000keys(array of string, required): min items 1; max items 32; each min length 1left_suffix(string, optional): min length 1; max length 32; default"_left"right_suffix(string, optional): min length 1; max length 32; default"_right"
Output
csv(string, required)rows_out(integer, required)
Limits
- max input bytes: 256000
- max data rows: 5000
- max columns: 256
- max header name bytes: 256
- max keys: 32
- max duplicate rows per key: 64
- max suffix chars: 32
- max output bytes: 256000
Example
Request input:
{
"left": "id,name,city\n1,Ada,London\n2,Lin,Paris\n3,Zoe,Rome\n",
"right": "id,dept,city\n1,Math,Cambridge\n1,CS,Oxford\n2,Physics,Paris\n4,Art,Berlin\n",
"keys": [
"id"
]
}
Response:
{
"result": {
"csv": "id,name,city_left,dept,city_right\n1,Ada,London,Math,Cambridge\n1,Ada,London,CS,Oxford\n2,Lin,Paris,Physics,Paris\n",
"rows_out": 3
}
}
How to call it
MCP
Connect https://computefirst.net/mcp (setup), then call execute with:
{
"id": "csv-inner-join",
"version": "1.0.0",
"input": {
"left": "id,name,city\n1,Ada,London\n2,Lin,Paris\n3,Zoe,Rome\n",
"right": "id,dept,city\n1,Math,Cambridge\n1,CS,Oxford\n2,Physics,Paris\n4,Art,Berlin\n",
"keys": [
"id"
]
}
}
HTTP (no key)
curl -X POST https://computefirst.net/v1/tools/csv-inner-join/versions/1.0.0/execute \
-H "Content-Type: application/json" \
-d '{"left":"id,name,city\n1,Ada,London\n2,Lin,Paris\n3,Zoe,Rome\n","right":"id,dept,city\n1,Math,Cambridge\n1,CS,Oxford\n2,Physics,Paris\n4,Art,Berlin\n","keys":["id"]}'
The machine-readable contract is at /v1/tools/csv-inner-join/versions/1.0.0.
CLI
node cli.mjs run csv-inner-join 1.0.0 --input input.json --base-url https://computefirst.net
Get the client at /clients/cli/.
Related tools
- CSV left join: Left join two CSV documents on exact named key columns.
- CSV anti join: Keep left CSV rows whose exact key tuples do not appear in the right document.
- CSV concat: Concatenate CSV documents that share identical headers, preserving document and row order.
- CSV merge columns: Join named CSV columns with an exact separator into one column.
- CSV reconcile: Reconcile two CSV documents by key columns, reporting full population totals and bounded samples for added, removed, changed, invalid-key, and ambiguous rows.
- CSV row diff: Compare two CSV documents with identical headers by unique key tuples and report added, removed, and changed rows.