Guide

How to query a CSV file with SQL

A CSV is already a table — it has columns, rows, and types. The only thing standing between it and a SQL query is usually a database import step nobody wants to do. This guide shows how to skip that step entirely and query the file directly.

Why not just use a spreadsheet?

Spreadsheets are excellent for small, hand-edited data and poor at repeatable questions. A nested IF over 200,000 rows is slow to write, slow to recalculate, and impossible to review later. SQL expresses the same question in one readable statement you can re-run whenever the file changes.

The usual objection is setup cost: installing Postgres, creating a schema, and writing a loader is disproportionate work for one afternoon of analysis. That objection disappears once the query engine can read the file where it sits.

Open the file and look at the schema first

Before writing a query, confirm what the parser actually inferred. Column names with trailing spaces, numbers that arrived as text, and dates in an ambiguous format cause more wrong answers than bad SQL does.

In NoEgress the Data Profile view shows each column's inferred type, null count, and distinct values. Check it before you trust an aggregate — a "revenue" column parsed as text will silently sort 9 above 100.

Start with SELECT and a LIMIT

Look at real rows before aggregating. This confirms the column names you will be typing for the rest of the session.

SELECT *
FROM orders
LIMIT 20;

Aggregate with GROUP BY

Most questions asked of a CSV are aggregations: totals per category, counts per month, averages per region. GROUP BY answers all of them with the same shape of query.

SELECT
  region,
  COUNT(*)          AS order_count,
  SUM(revenue)      AS total_revenue,
  AVG(revenue)      AS avg_order_value
FROM orders
WHERE order_date >= DATE '2026-01-01'
GROUP BY region
ORDER BY total_revenue DESC;

Combine two files with a JOIN

Open both files and each becomes its own table, so a lookup that would be a fragile VLOOKUP chain becomes an ordinary join.

Use a LEFT JOIN when you want to keep every row from the first file even if the second has no match — that is also the fastest way to find which keys are missing.

SELECT
  o.order_id,
  o.revenue,
  c.company_name
FROM orders o
LEFT JOIN customers c
  ON o.customer_id = c.customer_id
WHERE c.customer_id IS NULL;

Clean as you query, not before

Casting and trimming inside the query keeps the original file untouched, which means the transformation is visible and reviewable rather than baked into a copy of the data nobody can audit.

SELECT
  TRIM(customer_name)             AS customer_name,
  CAST(revenue AS DOUBLE)         AS revenue,
  CAST(order_date AS DATE)        AS order_date
FROM orders
WHERE revenue IS NOT NULL;

Where the query actually runs

NoEgress uses DuckDB compiled to WebAssembly, which means the engine is downloaded into the browser tab and the file is read from your disk by the browser. There is no upload step and no server-side copy — useful when the CSV contains customer records, salaries, or anything else you would rather not paste into a hosted tool.

Frequently asked

Do I need to install a database to run SQL on a CSV?

No. DuckDB can read the file directly, and in NoEgress it runs inside the browser tab, so there is nothing to install and no import step.

Which SQL dialect applies?

DuckDB SQL, which follows the PostgreSQL dialect closely. Standard SELECT, GROUP BY, JOIN, window functions, and CTEs all work as you would expect.

Can I query two CSV files together?

Yes. Open both and each becomes a table you can join in a single query.

Try it on your own file

More guides

How to open large CSV files Excel can't handle

How to run SQL on an Excel spreadsheet

How to analyze confidential data without uploading it

How to compare two CSV files and find what changed

Data quality checks to run before trusting a dataset

How to query a JSON file with SQL