CSV to SQLite Query Engine
Loads one or more CSV files into a real, in-browser SQLite database (via sql.js, SQLite compiled to WebAssembly) and lets you query them with actual SQL โ WHERE, GROUP BY, aggregate functions, and JOINs across multiple files, not a spreadsheet-style column filter. Each uploaded file becomes its own table named after the file, so joining two related CSVs is as simple as writing the JOIN. Numeric columns are only treated as numeric if every value actually parses as one, so comparisons and sorts work as numbers, not text; a blank cell becomes real SQL NULL, not an empty string. The database lives entirely in your browser's memory โ nothing is uploaded, and nothing persists once you leave the page.
Each file becomes its own table โ load more than one to JOIN across them.
About this tool
Loads one or more CSV files into a real, in-browser SQLite database (via sql.js, SQLite compiled to WebAssembly) and lets you query them with actual SQL โ not a spreadsheet-style column filter, the real thing: WHERE, GROUP BY, aggregate functions, and JOINs across multiple files. Each uploaded file becomes its own table, named after the file (sanitized to a valid SQL identifier), which is what makes joining two related CSVs โ an orders file and a customers file, say โ as simple as writing the JOIN yourself. Column types aren't guessed loosely: a column is only treated as numeric if every value in it actually parses as a number (the same rule tuliq's chart tools use), so a WHERE or ORDER BY on a numeric column compares as numbers, not as text โ the classic spreadsheet-tool bug where "10" sorts before "9". A blank cell becomes real SQL NULL, not an empty string or a silent zero, so COUNT, AVG, and IS NULL all behave the way they would against a real database. The whole database exists only in your browser's memory for as long as the tab is open โ there's no server, no persistence, and no upload at any point.
What you can do
- Real SQLite, compiled to WebAssembly โ full SQL, not a spreadsheet-style filter
- Load multiple CSVs at once โ each becomes its own table you can JOIN across
- Numeric columns are detected automatically, so WHERE and ORDER BY compare as numbers, not text
- The database lives entirely in your browser's memory โ nothing is uploaded, nothing persists after you leave
How to use
Step 1
Load one or more CSVs
Each file becomes its own table, named after the file.
Step 2
Write a SQL query
SELECT, WHERE, GROUP BY, JOIN across tables โ anything SQLite supports.
Step 3
Run it
Ctrl+Enter (โ+Enter on Mac) also runs the query, so you don't need to reach for the mouse.
Example
Loading orders.csv and customers.csv, you could join them directly:
query.sql
SELECT c.name, SUM(o.amount) AS total FROM "orders" o JOIN "customers" c ON o.customer_id = c.customer_id GROUP BY c.name ORDER BY total DESC;
Table names come from the file name (lowercased, non-identifier characters collapsed to underscores) โ "Sales Data.csv" becomes the table "sales_data".
How your data is handled
This tool is labeled ๐ข Runs in your browser: sql.js runs entirely client-side via WebAssembly, and the database it builds exists only in your browser's memory. Nothing about your files or your queries is ever uploaded, logged, or sent anywhere โ closing or refreshing the tab discards the whole database, since none of it is saved to disk.
Frequently asked questions
What SQL features are supported?+
Everything SQLite supports โ SELECT, WHERE, GROUP BY, HAVING, ORDER BY, JOINs, subqueries, aggregate functions (SUM, AVG, COUNT, MIN, MAX), and SQLite's own functions. This is real SQLite, not a simplified subset.
Can I query across two different CSV files?+
Yes โ load both files (each becomes its own table named after the file) and JOIN them in your query, exactly as you would with two real database tables.
How are column types decided?+
A column is treated as numeric (SQLite REAL) only if every non-empty value in it parses as a number โ one stray label anywhere in the column keeps the whole column as TEXT. This matches how tuliq's chart tools decide the same thing, so results stay consistent across tools.
What happens to blank cells?+
They become real SQL NULL, not an empty string or a zero โ so COUNT(column), AVG(column), and IS NULL all behave correctly, the way they would against an actual database.
Is my data uploaded anywhere?+
No โ sql.js runs entirely in your browser via WebAssembly, and the database it builds lives only in your browser's memory for as long as the tab stays open. Nothing is sent to a server at any point.
Does my database persist if I reload the page?+
No โ there's no save/persistence step by design. Reloading or closing the tab discards the database entirely; re-load your CSVs to start again.