Updated 2026-10-05 · By Sergi (spnfury)
SQL is the most natural way to ask a question of tabular data: which customers ordered more than three times, revenue per month, duplicated emails. You do not need a database server to do it. Several tools read a CSV directly and let you query it as if it were a table.
This guide compares five of them, from a browser tool for a one-off question to DuckDB for gigabytes of data, with the exact command for each.
| Tool | Where it runs | Install | Types inferred | Joins | Best for |
|---|---|---|---|---|---|
| CSV Creator (AlaSQL) | Browser | None | Numbers | No (single CSV) | One quick question, private data |
| DuckDB CLI | Terminal | Single binary | Yes, all | Yes | Large files, analytics |
| q (harelba/q) | Terminal | Binary or pip | Yes | Yes | Shell pipelines |
| csvkit csvsql | Terminal | pip | Yes | Yes | Python users, csvkit suite |
| SQLite .import | Terminal | Usually preinstalled | No (all text) | Yes | Keeping the data for later |
Paste the CSV, write a query with FROM ? as the table name, click Execute. The engine is AlaSQL, a SQL implementation in JavaScript, so the data never leaves the page. Numeric-looking cells are converted to numbers, which makes SUM and AVG work; quoted fields with commas are supported.
It covers SELECT with WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, the usual aggregates, CASE, LIKE, IN, subqueries and string functions. What it cannot do is join two files, because only one CSV is loaded. Results can be downloaded as a new CSV.
SELECT city, COUNT(*) AS orders, SUM(amount) AS revenue FROM ? GROUP BY city ORDER BY revenue DESC
DuckDB is an embedded analytical database that reads CSV files directly, infers types including dates, and runs queries over gigabytes in seconds. The CLI is a single binary with no dependencies.
duckdb -c "SELECT city, COUNT(*), SUM(amount) FROM read_csv_auto('orders.csv') GROUP BY city ORDER BY 3 DESC"
q treats the CSV as a table named after the file and accepts standard SQLite syntax. It shines in pipes: cat a log, query it, pass the result on.
q -H -d , "SELECT city, COUNT(*) FROM ./orders.csv GROUP BY city"
csvkit is a Python suite for CSV work (csvcut, csvgrep, csvstat...). csvsql loads the file into an in-memory SQLite database and runs your query.
csvsql --query "SELECT city, COUNT(*) AS n FROM orders GROUP BY city" orders.csv
SQLite ships with most operating systems. Importing a CSV creates a table you can keep, index and query repeatedly.
sqlite3 orders.db .mode csv .import orders.csv orders SELECT city, COUNT(*) FROM orders GROUP BY city;
Yes. CSV Creator's Query CSV with SQL runs a JavaScript SQL engine (AlaSQL) in your browser: paste the CSV, write SELECT ... FROM ? and execute. Nothing is installed and nothing is uploaded.
SQLite is a transactional row store that needs the CSV imported first and treats every column as text. DuckDB is a columnar analytical engine that reads the CSV directly, infers types and runs aggregations far faster on large files. For analysis use DuckDB; to store and edit records use SQLite.
The column contains values that are not plain numbers: thousands separators, currency symbols, spaces. Browser tools and q only convert clean decimals. Clean the column or CAST it in the query; DuckDB can be told the type explicitly in read_csv.
Use a tool that loads several files as tables: DuckDB (read_csv_auto on each file), q (two file names in FROM), csvsql (pass both files) or SQLite after importing both. Browser tools that load a single CSV cannot join.
Only with tools that run in the browser without uploading, such as CSV Creator. Check the network tab in developer tools: no request should carry your data. For maximum control use a local tool such as DuckDB or q.