# CSV Coalesce Columns

Merge CSV columns into one by taking the first non-empty value per row, in the priority order you choose. Add a fallback, drop the sources. Free, in-browser.

## Run it

- **CLI:** `gizza tool csv-coalesce-columns "name,mobile,office,home
Ann,555-1,555-2,555-3
Bob,,555-4,555-5
Cleo,,,555-6" 'columns=mobile,office,home'`
- **Web:** https://gizza.ai/tools/csv-coalesce-columns/
- **Agents:** machine-readable descriptor (parameters JSON Schema) at https://gizza.ai/tools/csv-coalesce-columns/tool.json

## Inputs

- `data` — CSV _(field)_
- `columns` — Source columns, highest priority first _(field)_
- `output` — New column name (blank = coalesced) _(field)_
- `position` — Put the new column _(field)_
- `fallback` — Fallback when every source is empty _(field)_
- `drop_sources` — Drop the source columns _(field)_
- `blank_is_empty` — Treat whitespace-only cells as empty _(field)_
- `null_tokens` — Extra placeholders that count as empty _(field)_
- `header` — First row is a header _(field)_
- `delimiter` — Delimiter (, tab ; |) _(field)_

## Output

- Coalesced CSV (text)

## Query parameters

Open the tool pre-filled and auto-run via URL:

- `data` — CSV
- `columns` — Source columns, highest priority first
- `output` — New column name (blank = coalesced)
- `position` — Put the new column
- `fallback` — Fallback when every source is empty
- `drop_sources` — Drop the source columns
- `blank_is_empty` — Treat whitespace-only cells as empty
- `null_tokens` — Extra placeholders that count as empty
- `header` — First row is a header
- `delimiter` — Delimiter (, tab ; |)

Example: `https://gizza.ai/tools/csv-coalesce-columns/?data=name%2Cmobile%2Coffice%2Chome%0AAnn%2C555-1%2C555-2%2C555-3%0ABob%2C%2C555-4%2C555-5%0ACleo%2C%2C%2C555-6&columns=mobile%2Coffice%2Chome&output=phone&position=end&fallback=N%2FA&drop_sources=true&blank_is_empty=true&null_tokens=NULL%2CNA%2CN%2FA%2C-&header=true&delimiter=%2C`

---

## CSV coalesce columns

Build **one** column from the first non-empty value across several columns, read
in the priority order you list them — the SQL `COALESCE` idea applied to columns
instead of expressions. It's the fastest way to fold `mobile`/`office`/`home`
into a single `phone`, or a web price with a list-price fallback, without writing
a spreadsheet formula. Optionally drop the source columns, choose where the new
column lands, and set a fallback for rows where every source is empty. Runs
entirely in your browser; nothing is uploaded.

### Worked example

Input — three phone columns, filled in unevenly:

```
name,mobile,office,home
Ann,555-1,555-2,555-3
Bob,,555-4,555-5
Cleo,,,555-6
```

Source columns `mobile,office,home`, new column name `phone` → output:

```
name,mobile,office,home,phone
Ann,555-1,555-2,555-3,555-1
Bob,,555-4,555-5,555-4
Cleo,,,555-6,555-6
```

Ann keeps her mobile (first in the priority list), Bob falls through to the
office number, Cleo all the way to home. Turn on **Drop the source columns** and
set the position to *where the first source column was* to get the tidy version
instead:

```
name,phone
Ann,555-1
Bob,555-4
Cleo,555-6
```

### Options

- **Source columns** — comma-separated, **highest priority first**: header names
  (`mobile,office,home`) or 1-based indices (`2,3,4`). A purely numeric token is
  always read as an index, so a column literally named `2` must be addressed by
  its position.
- **New column name** — blank uses `coalesced`. It must not clash with a column
  you keep.
- **Put the new column** — at the end, at the start, or where the first source
  column sat.
- **Fallback** — written when *every* source is empty for that row (`N/A`,
  `unknown`, …). Blank leaves the cell empty.
- **Drop the source columns** — removes them after merging, so only the new
  column remains.
- **Treat whitespace-only cells as empty** — on by default, so a stray space is
  skipped rather than winning.
- **Extra placeholders that count as empty** — comma-separated tokens such as
  `NULL,NA,N/A,-`, matched case-insensitively against the trimmed cell.
- **First row is a header** — keeps and rewrites the header row, and lets you
  name columns instead of counting them.
- **Delimiter** — comma, tab, semicolon, pipe, or any single character.

### Limits & edge cases

- Only *emptiness* decides the winner — no type checks, no `0`/`false` special
  case. A cell containing `0` is a real value and wins.
- Placeholders like `NULL` or `N/A` are ordinary text unless you list them under
  **Extra placeholders that count as empty**.
- Rows shorter than the widest row are padded with empty cells, so a missing
  trailing column simply falls through to the next source.
- Listing the same column twice, naming a column that isn't in the header, or
  using an index past the last column is an error rather than a silent skip.
- The new column's name must not collide with a column you keep — rename it, or
  drop the sources.
- Values are copied verbatim (quotes, inner commas, unicode); the tool never
  reformats or trims the value it picks.

### FAQ

<details>
<summary>How is this different from concatenating or merging columns?</summary>

Concatenating joins *every* value together (`555-1 / 555-2`). Coalescing picks
exactly **one** — the first source that has a value for that row — and ignores
the rest. Use it when the columns are alternatives for the same fact, not parts
of one.

</details>

<details>
<summary>What counts as an empty cell?</summary>

A zero-length cell always counts. With **Treat whitespace-only cells as empty**
on (the default), a cell holding only spaces or tabs counts too. Anything you
list under **Extra placeholders that count as empty** — for example
`NULL,NA,N/A,-` — also counts, compared case-insensitively after trimming, so
`n/a` and `N/A` both match.

</details>

<details>
<summary>Can I keep the original columns?</summary>

Yes — that's the default. The new column is added alongside them, so you can
check the result before deleting anything. Turn on **Drop the source columns**
only when you want them replaced; other columns are always kept in their
original order.

</details>

<details>
<summary>Does it work without a header row?</summary>

Yes. Switch **First row is a header** off and address columns by 1-based index
(`2,3,4`). Every row is then treated as data, and the coalesced column is added
without a header cell.

</details>

<details>
<summary>Is my data uploaded?</summary>

No — the CSV is processed locally with WebAssembly. Nothing leaves your browser.

</details>

## Related tools

- [Absolute value, sign, or negation for a whole column](https://gizza.ai/tools/absolute-value-transformer/): Paste a column of numbers and apply absolute value, sign extraction (-1/0/1), sign flipping, or force-negative to every value at once, with rounding and an audit table.
- [Adjacency Matrix Converter](https://gizza.ai/tools/adjacency-matrix-converter/): Convert a graph between edge list, adjacency matrix, and incidence matrix — directed or undirected, weighted or not. Free, private, runs in your browser.
- [Amazon Order Analyzer](https://gizza.ai/tools/amazon-order-analyzer/): Paste an Amazon order-history CSV export to summarize total spend by month, top items, and category breakdowns. Browser-only, private, with Markdown or JSON output.
- [ARFF Converter](https://gizza.ai/tools/arff-converter/): Convert Weka ARFF datasets to CSV and CSV tables back to ARFF locally — nominal attributes, numeric types, dates, sparse rows, missing values, and type rows.
- [Avro to JSON Converter](https://gizza.ai/tools/avro-to-json/): Decode Apache Avro Object Container Files (.avro / OCF) to JSON, NDJSON, or the embedded schema — no .avsc needed, free and private in your browser.
