Guide · 2 min read

Query CSV files with SQL — without a database.

Every open file is a table named after itself. Join a CSV to a workbook, group and sum, save the query as a view, and open the answer as a new file.

The idea

A CSV file is a table; SQL is the language for asking tables questions. Usually you would have to create a database, define a table and import the file first. In Intact CSV Editor the query console treats every open document as a table already — named after its file, customers.csv as customers — and copies in only the tables a statement names.

Your first query

  1. Open the file — a CSV, a workbook, a Parquet file, anything the app reads.
  2. Press ⇧⌘R to open the query window. The sidebar lists the tables and their columns.
  3. Type a statement and press ⌘R:
    SELECT city, COUNT(*) AS customers, SUM(revenue_chf) AS revenue
    FROM customers
    GROUP BY city
    ORDER BY revenue DESC;
  4. Use the result: replace the table with it, export it to any format, or open it as a new document.

Columns that look numeric become real numbers for the query, so 1'234.50 and 987,25 compare and add up correctly — while the file itself keeps them exactly as written.

Joining two files

SELECT c.name, o.order_id, o.amount
FROM customers c
JOIN orders o USING (customer_no)
WHERE o.date >= '2026-01-01';

A file that is not open can be named by its path: SELECT * FROM "@file:/Exports/archive.csv".

MySQL, on SQLite

The engine underneath is SQLite; on top of it the dialect is MySQL's. Backtick identifiers, # comments, SHOW TABLES, DESCRIBE, GROUP_CONCAT(… SEPARATOR …), DATE_FORMAT, STR_TO_DATE, REGEXP_REPLACE, JSON_EXTRACT and most of MySQL's function library work as they do there, and a MySQL dump can be pasted in as it stands. Switch MySQL mode off in Settings for plain SQLite.

Regular expressions — RLIKE, REGEXP_LIKE, REGEXP_REPLACE — are compiled once per query rather than once per row: a grouped query with RLIKE over a million rows takes about 0.9 seconds. A pattern that can take exponential time, a repeat inside a repeat such as (a+)+b, is refused with a message saying why, instead of freezing the window on the first long value.

Views and long results

Save a query under a name and it becomes a table of its own — SELECT * FROM open_items — which remembers the files it is built from and can be opened as a document that is always current. Results longer than the console shows are read a page at a time, 101–200 of 4,318, without rewriting your statement.

Other ways to do it

On the command line, sqlite3 can import a CSV with .import, csvkit's csvsql runs SQL on CSV files, and DuckDB reads CSV and Parquet directly. They are excellent in a terminal; Intact CSV Editor puts the same questions next to the grid, where you can see and fix the data the answer came from.

Try it on your own file

Intact CSV Editor is in beta. Join the beta and we will write to you as soon as your access is ready.

Questions

Common questions

Can I run SQL on a CSV file without importing it?

Yes. Open the file in Intact CSV Editor and press ⇧⌘R; the file is a table named after itself.

Which SQL dialect is it?

MySQL-flavoured on SQLite: MySQL's syntax and function library, SQLite's engine. Plain SQLite is a setting away.

Can I join a CSV with an Excel file?

Yes — every open document is a table, whatever its format.

Open your most difficult file.

Join the beta and we will write to you as soon as your access is ready. Your files never leave your Mac.

macOS 14 Sonoma or later · How we use your address