Course page
Log in

You are watching a free preview. Enroll to open all 24 lessons, track progress and ask the course tutor.

Enroll for $29.99

Section 1: Getting productive with DuckDB

Querying CSV, Parquet and JSON files

Article 12 min Lesson 2 of 24 Preview

Most analysis starts with files. DuckDB can read them individually, in groups, and with control over how they are parsed.

Parquet: the easy case

SELECT start_station, count(*) AS trips
FROM 'data/trips/*.parquet'
GROUP BY start_station
ORDER BY trips DESC
LIMIT 10;

The glob pattern reads every file in the folder as one table. If the files are stored in Hive style folders such as year=2026/month=01/, add hive_partitioning = true and the folder names become columns you can filter on, letting DuckDB skip whole folders:

SELECT count(*)
FROM read_parquet('data/trips/*/*/*.parquet', hive_partitioning = true)
WHERE year = 2026 AND month = 1;

CSV: let it sniff, then check

read_csv detects the delimiter, header, quoting and column types by sampling the file.

DESCRIBE SELECT * FROM read_csv('stations.csv');

DESCRIBE shows the detected types. If a column was guessed wrong, for example postal codes read as integers losing their leading zeros, override it:

SELECT * FROM read_csv('stations.csv', types = {'postal_code': 'VARCHAR'});

For truly messy files, ignore_errors = true skips bad lines, and store_rejects = true keeps them in a rejects table so you can see what was skipped instead of losing rows silently.

JSON: records and nesting

SELECT * FROM read_json('events.json') LIMIT 5;

Newline delimited JSON and arrays of objects are both detected. Nested objects become STRUCT columns, which you can access with dot notation, and lists can be expanded with unnest:

SELECT e.user.id AS user_id, unnest(e.items) AS item
FROM read_json('events.json') AS e;

Turn files into tables when it helps

Querying files directly is great for exploration. When you will query the same data many times, store it in the DuckDB database file:

CREATE TABLE trips AS SELECT * FROM 'data/trips/*.parquet';

DuckDB's own storage format is compressed and columnar, so this is fast and compact.

← → switch lessons