# Demote headers to a row

Shape / columns

A variant of [Promote a row to headers](https://meridian.online/operations/promote-a-row-to-headers).

Move the column names into a new first data row and give the columns default names.

Page: <https://meridian.online/operations/promote-a-row-to-headers/demote-headers-to-a-row>

## Status

Runs as a SQL step.

arcform carries it as a `sql:` step today.

## The DuckDB step

demote the header line to a first data row and name the columns by default

```sql
COPY (SELECT 1 AS id, 'a' AS name UNION ALL SELECT 2, 'b') TO '<your_scratch_dir>/named.csv' (HEADER);
CREATE TEMP TABLE result AS
SELECT * FROM read_csv('<your_scratch_dir>/named.csv', header = false, all_varchar = true);
SELECT * FROM result;
SELECT CASE WHEN ((SELECT list(column_name) FROM (DESCRIBE result)) = ['column0', 'column1'] AND (SELECT count(*) FROM result) = 3 AND (SELECT list(column0 ORDER BY rowid) FROM result) = ['id', '1', '2'] AND (SELECT list(column1 ORDER BY rowid) FROM result) = ['name', 'a', 'b']) THEN 'as expected' ELSE error('the header line did not become the first data row under the default names column0 and column1, ahead of the two data rows') END AS verdict;
```

Replace `<your_scratch_dir>` with a directory of your own that you can write to before running the statement.

The statement writes `named.csv` itself, in `<your_scratch_dir>`.

It needs nothing installed beyond DuckDB itself.

## What other tools call it

Meridian's classification; an independent blind rating agreed on 95.7% of 324 rows (variant, version 3).

- Power Query M: [`Table.DemoteHeaders`](https://learn.microsoft.com/en-us/powerquery-m/table-functions#column-operations) (read 2026-09-27)
