SQLite Cheat Sheet
SQLite is a lightweight SQL database engine and sqlite3 is its command-line interface. This SQLite cheatsheet provides an advanced, scan-friendly reference for installing SQLite, creating databases and tables, querying data, controlling transactions, using PRAGMA settings, inspecting schema, and exporting/importing data.
Install sqlite3
Install the SQLite CLI on common platforms.
# Debian/Ubuntu
sudo apt-get update
sudo apt-get install -y sqlite3
# Fedora
sudo dnf install -y sqlite
# macOS (Homebrew)
brew install sqlite
# Windows (PowerShell, example with winget if available)
winget install SQLite.SQLite
sqlite3 --version
# 3.xx.x 202x-xx-xx ...
Create or open a database file
Opening a database file creates it if it does not exist.
sqlite3 path/to/app.db
SQLite version 3.xx.x
Enter ".help" for usage hints.
sqlite>
Open an in-memory database
The special name :memory: creates a database that lives only in memory for the life of the connection.
sqlite3 :memory:
sqlite> .databases
main: "" r/w
Exit sqlite3
Exit the interactive shell.
.quit
.exit
sqlite> .quit
Show help for sqlite3 meta-commands
List dot-commands supported by the CLI.
.help
sqlite> .help
.archive ... .databases ... .tables ...
List databases and attachments
Display attached databases and file paths.
.databases
sqlite> .databases
main: /tmp/app.db r/w
Open a different database in the same session
Switch the active database file.
.open FILENAME
sqlite> .open other.db
sqlite> .databases
main: /tmp/other.db r/w
Attach and detach databases
Attach additional database files under a schema name.
ATTACH DATABASE 'analytics.db' AS analytics;
DETACH DATABASE analytics;
ATTACH DATABASE 'analytics.db' AS analytics;
SELECT name FROM analytics.sqlite_master WHERE type='table';
DETACH DATABASE analytics;
Configure output to table mode
Table mode renders results in a grid format.
.mode table
.headers on
sqlite> .mode table
sqlite> .headers on
sqlite> SELECT 1 AS id, 'ok' AS status;
id status
-- ------
1 ok
Configure output to CSV mode
CSV mode is useful for exporting query results.
.mode csv
.separator ,
sqlite> .mode csv
sqlite> .separator ,
sqlite> SELECT 1,'a';
1,a
Redirect output to a file
Send subsequent query output to a file, then restore to stdout.
.output FILENAME
.output stdout
sqlite> .output out.csv
sqlite> SELECT 'id','name' UNION ALL SELECT 1,'Alice';
sqlite> .output stdout
Execute SQL from a file
Run a .sql file inside the current session.
.read FILENAME.sql
sqlite> .read schema.sql
Dump a database as SQL
Dump schema and data as SQL statements.
.dump
.dump table_name
sqlite> .output backup.sql
sqlite> .dump
sqlite> .output stdout
Backup a live database
Create a consistent backup from within sqlite3.
.backup FILENAME
sqlite> .backup backup.db
Restore a database from a backup
Replace the current database contents with a backup file.
.restore FILENAME
sqlite> .restore backup.db
Import CSV into a table
Import a CSV file into an existing table.
.mode csv
.import FILE.csv table_name
sqlite> .mode csv
sqlite> .import users.csv users
SQLite storage classes and type affinity
SQLite uses storage classes for values and type affinity for columns.
Storage classes: NULL, INTEGER, REAL, TEXT, BLOB
Type affinities: TEXT, NUMERIC, INTEGER, REAL, BLOB
SELECT typeof(123) AS t1, typeof(123.4) AS t2, typeof('x') AS t3, typeof(x'00') AS t4, typeof(NULL) AS t5;
t1 t2 t3 t4 t5
------- ----- ---- ---- ----
integer real text blob null
Data types table
Common declared type names map to affinities; values are stored using storage classes.
| Declared Type Examples | Affinity | Typical Use |
|---|---|---|
INT, INTEGER, BIGINT, TINYINT |
INTEGER |
Integers and row identifiers |
REAL, DOUBLE, FLOAT |
REAL |
Floating-point numbers |
NUMERIC, DECIMAL, BOOLEAN, DATE, DATETIME |
NUMERIC |
Numbers/dates stored with numeric conversion rules |
CHAR(n), VARCHAR(n), TEXT, CLOB |
TEXT |
Text data |
BLOB |
BLOB |
Binary data |
Create a table
Create a basic table with common constraints.
CREATE TABLE users (
id INTEGER PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
display_name TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
INSERT INTO users (email, display_name) VALUES ('a@example.com', 'Alice');
SELECT id, email, display_name, created_at FROM users;
1|a@example.com|Alice|2025-12-27 00:00:00
INTEGER PRIMARY KEY and rowid
INTEGER PRIMARY KEY is an alias for the internal rowid and auto-assigns values when omitted.
CREATE TABLE t (
id INTEGER PRIMARY KEY,
v TEXT
);
INSERT INTO t (v) VALUES ('x'), ('y');
SELECT rowid, id, v FROM t;
1|1|x
2|2|y
WITHOUT ROWID tables
WITHOUT ROWID stores rows as a B-tree keyed by the PRIMARY KEY instead of an implicit rowid.
CREATE TABLE kv (
k TEXT PRIMARY KEY,
v BLOB
) WITHOUT ROWID;
INSERT INTO kv (k, v) VALUES ('a', x'0102');
SELECT k, length(v) FROM kv;
a|2
Composite primary keys and UNIQUE constraints
Define multi-column keys and separate uniqueness constraints.
CREATE TABLE enrollment (
course_code TEXT NOT NULL,
student_id TEXT NOT NULL,
enrolled_at TEXT NOT NULL DEFAULT (datetime('now')),
PRIMARY KEY (course_code, student_id),
UNIQUE (student_id, enrolled_at)
);
INSERT INTO enrollment(course_code, student_id) VALUES ('CS101','s1');
SELECT course_code, student_id FROM enrollment;
CS101|s1
NOT NULL constraint
Prevent inserting NULL in required columns.
CREATE TABLE items (
sku TEXT NOT NULL,
price REAL NOT NULL
);
INSERT INTO items (sku, price) VALUES ('X1', 9.99);
SELECT sku, price FROM items;
X1|9.99
Foreign keys (enable and verify)
Foreign key enforcement must be enabled per connection.
PRAGMA foreign_keys = ON;
PRAGMA foreign_key_check;
PRAGMA foreign_keys = ON;
CREATE TABLE parent (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE child (
id INTEGER PRIMARY KEY,
parent_id INTEGER NOT NULL,
FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ON DELETE SET NULL
);
PRAGMA foreign_key_check;
-- (no rows means no violations)
Insert rows
Insert with explicit column list or defaulted columns.
INSERT INTO users (email, display_name) VALUES (?, ?);
INSERT INTO users (email) VALUES ('b@example.com');
INSERT INTO users (email, display_name) VALUES ('c@example.com', 'Carol');
SELECT id, email, display_name FROM users ORDER BY id;
1|a@example.com|Alice
2|b@example.com|
3|c@example.com|Carol
Update rows
Update with computed expressions and filtered targets.
UPDATE users
SET display_name = upper(display_name)
WHERE display_name IS NOT NULL;
SELECT id, display_name FROM users ORDER BY id;
1|ALICE
2|
3|CAROL
Delete rows
Delete by condition or clear a table.
DELETE FROM users WHERE id = 2;
DELETE FROM users; -- removes all rows
DELETE FROM users WHERE id = 2;
SELECT COUNT(*) FROM users;
2
Select query structure
Standard SELECT clause ordering in SQLite.
SELECT select_list
FROM table_or_subquery
WHERE predicate
GROUP BY group_list
HAVING group_predicate
ORDER BY order_list
LIMIT count OFFSET offset;
SELECT email
FROM users
WHERE email LIKE '%@example.com'
ORDER BY email
LIMIT 10 OFFSET 0;
a@example.com
c@example.com
Join tables
Join tables with explicit ON conditions.
SELECT c.id, c.parent_id, p.name
FROM child AS c
JOIN parent AS p
ON p.id = c.parent_id;
SELECT c.id, p.name
FROM child c
JOIN parent p ON p.id = c.parent_id;
-- (result depends on inserted data)
Left join and NULL extension
Rows with no match in the right table produce NULLs.
SELECT p.id, p.name, c.id AS child_id
FROM parent p
LEFT JOIN child c ON c.parent_id = p.id
ORDER BY p.id;
SELECT p.id, p.name, c.id AS child_id
FROM parent p
LEFT JOIN child c ON c.parent_id = p.id;
1|ParentName|NULL
Grouping and aggregates
Aggregate functions compute per-group values.
SELECT parent_id, COUNT(*) AS child_count
FROM child
GROUP BY parent_id
HAVING COUNT(*) >= 1
ORDER BY child_count DESC;
SELECT parent_id, COUNT(*) AS child_count
FROM child
GROUP BY parent_id;
1|3
2|1
Sorting and pagination
Sort and page with ORDER BY, LIMIT, and OFFSET.
SELECT id, email
FROM users
ORDER BY id
LIMIT 20 OFFSET 40;
SELECT id, email
FROM users
ORDER BY id
LIMIT 2 OFFSET 0;
1|a@example.com
3|c@example.com
Common Table Expressions (CTE)
CTEs define named subqueries for a single statement.
WITH active_users AS (
SELECT id, email
FROM users
WHERE display_name IS NOT NULL
)
SELECT * FROM active_users ORDER BY id;
WITH u AS (SELECT id, email FROM users)
SELECT COUNT(*) FROM u;
2
Recursive CTE
Recursive CTEs iterate over hierarchical data.
WITH RECURSIVE seq(n) AS (
SELECT 1
UNION ALL
SELECT n + 1 FROM seq WHERE n < 5
)
SELECT n FROM seq;
WITH RECURSIVE seq(n) AS (
SELECT 1
UNION ALL
SELECT n + 1 FROM seq WHERE n < 3
)
SELECT group_concat(n, ',') FROM seq;
1,2,3
Create an index
Indexes speed lookup and sorting for predicates and ORDER BY expressions.
CREATE INDEX idx_users_email ON users(email);
CREATE UNIQUE INDEX idx_users_email_uq ON users(email);
DROP INDEX idx_users_email;
CREATE INDEX idx_child_parent ON child(parent_id);
PRAGMA index_list('child');
0|idx_child_parent|0|c|0
Expression index
Index an expression used in predicates.
CREATE INDEX idx_users_email_lower ON users(lower(email));
SELECT id FROM users WHERE lower(email) = 'a@example.com';
EXPLAIN QUERY PLAN SELECT id FROM users WHERE lower(email) = 'a@example.com';
SEARCH users USING INDEX idx_users_email_lower (<expr>=?)
Create a view
Views store a named SELECT for reuse.
CREATE VIEW v_user_emails AS
SELECT id, email
FROM users
WHERE email IS NOT NULL;
SELECT * FROM v_user_emails ORDER BY id;
1|a@example.com
3|c@example.com
Create a trigger
Triggers execute SQL automatically on INSERT/UPDATE/DELETE events.
CREATE TABLE audit_log (
id INTEGER PRIMARY KEY,
table_name TEXT NOT NULL,
action TEXT NOT NULL,
row_id INTEGER,
at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TRIGGER users_ai
AFTER INSERT ON users
BEGIN
INSERT INTO audit_log(table_name, action, row_id)
VALUES ('users', 'INSERT', new.id);
END;
INSERT INTO users (email, display_name) VALUES ('d@example.com','Dan');
SELECT table_name, action, row_id FROM audit_log ORDER BY id DESC LIMIT 1;
users|INSERT|4
Begin a transaction
Group statements into an atomic unit of work.
BEGIN;
-- statements
COMMIT;
-- or:
ROLLBACK;
BEGIN;
UPDATE users SET display_name = 'X' WHERE id = 9999;
ROLLBACK;
-- ROLLBACK completed
Savepoints
Savepoints allow partial rollback within a transaction.
BEGIN;
SAVEPOINT sp1;
-- statements
ROLLBACK TO sp1;
RELEASE sp1;
COMMIT;
BEGIN;
SAVEPOINT sp1;
INSERT INTO users (email) VALUES ('e@example.com');
ROLLBACK TO sp1;
RELEASE sp1;
COMMIT;
-- Insert rolled back to savepoint
EXPLAIN QUERY PLAN
Show how SQLite intends to execute a query.
EXPLAIN QUERY PLAN
SELECT * FROM users WHERE email = 'a@example.com';
EXPLAIN QUERY PLAN
SELECT * FROM users WHERE email = 'a@example.com';
SEARCH users USING INDEX idx_users_email (email=?)
ANALYZE
Collect statistics to help the query planner choose indexes.
ANALYZE;
ANALYZE table_name;
ANALYZE;
SELECT name FROM sqlite_master WHERE type='table';
users
child
parent
VACUUM
Rebuild the database file to reclaim free space.
VACUUM;
VACUUM;
PRAGMA page_count;
-- page_count is engine- and DB-dependent
PRAGMA journal_mode
Query or set journaling mode.
PRAGMA journal_mode;
PRAGMA journal_mode = WAL;
PRAGMA journal_mode;
PRAGMA journal_mode = WAL;
PRAGMA journal_mode;
delete
wal
PRAGMA synchronous
Control the synchronization level for transactions.
PRAGMA synchronous;
PRAGMA synchronous = OFF|NORMAL|FULL|EXTRA;
PRAGMA synchronous;
PRAGMA synchronous = NORMAL;
PRAGMA synchronous;
2
1
PRAGMA busy_timeout
Set how long SQLite waits when a table is locked.
PRAGMA busy_timeout;
PRAGMA busy_timeout = 5000;
PRAGMA busy_timeout = 2000;
PRAGMA busy_timeout;
2000
PRAGMA cache_size
Configure page cache size (units depend on sign and build).
PRAGMA cache_size;
PRAGMA cache_size = 2000;
PRAGMA cache_size = 4000;
PRAGMA cache_size;
4000
PRAGMA temp_store
Control where temporary tables and indices are stored.
PRAGMA temp_store;
PRAGMA temp_store = DEFAULT|FILE|MEMORY;
PRAGMA temp_store = MEMORY;
PRAGMA temp_store;
2
PRAGMA mmap_size
Control the memory-mapped I/O region size.
PRAGMA mmap_size;
PRAGMA mmap_size = 268435456;
PRAGMA mmap_size = 134217728;
PRAGMA mmap_size;
134217728
PRAGMA wal_checkpoint
Checkpoint WAL content back into the main database file.
PRAGMA wal_checkpoint;
PRAGMA wal_checkpoint(FULL);
PRAGMA wal_checkpoint(TRUNCATE);
PRAGMA wal_checkpoint;
0|0|0
PRAGMA integrity_check and quick_check
Validate database integrity; quick_check skips some validations.
PRAGMA integrity_check;
PRAGMA quick_check;
PRAGMA quick_check;
ok
PRAGMA optimize
Run optimizer maintenance tasks.
PRAGMA optimize;
PRAGMA optimize(-1);
PRAGMA optimize;
-- (no output on success in many builds)
Schema introspection via PRAGMA
Inspect columns, indexes, and foreign keys.
PRAGMA table_info('users');
PRAGMA index_list('users');
PRAGMA index_info('idx_users_email');
PRAGMA foreign_key_list('child');
PRAGMA table_info('users');
0|id|INTEGER|0||1
1|email|TEXT|1||0
2|display_name|TEXT|0||0
3|created_at|TEXT|1|datetime('now')|0
sqlite_master catalog query
Use sqlite_master to list schema objects and their SQL definitions.
SELECT type, name, tbl_name, sql
FROM sqlite_master
WHERE type IN ('table','index','view','trigger')
ORDER BY type, name;
SELECT type, name
FROM sqlite_master
ORDER BY type, name;
index|idx_users_email
table|users
view|v_user_emails
FTS5 virtual table
Full-text search using the FTS5 extension.
CREATE VIRTUAL TABLE docs USING fts5(title, body);
INSERT INTO docs(title, body) VALUES ('Intro', 'SQLite full text search');
SELECT rowid, title FROM docs WHERE docs MATCH 'text';
1|Intro
JSON functions (JSON1)
Query JSON content stored in TEXT columns when JSON1 is available.
SELECT json_extract(data, '$.user.id') AS user_id
FROM events
WHERE json_type(data, '$.user.id') IS NOT NULL;
CREATE TABLE events (id INTEGER PRIMARY KEY, data TEXT);
INSERT INTO events(data) VALUES ('{"user":{"id":42}}');
SELECT json_extract(data, '$.user.id') FROM events;
42
STRICT tables
STRICT tables enforce type constraints more strictly (SQLite feature).
CREATE TABLE strict_users (
id INTEGER PRIMARY KEY,
age INTEGER NOT NULL
) STRICT;
INSERT INTO strict_users(age) VALUES (30);
SELECT id, age FROM strict_users;
1|30
Date and time functions
SQLite provides built-in date/time functions that return TEXT by default.
SELECT date('now'), time('now'), datetime('now');
SELECT datetime('now','-7 days'), datetime('now','start of month');
SELECT datetime('now') AS now_utc;
2025-12-27 00:00:00
Common CLI schema browsing
List tables and show CREATE statements quickly in sqlite3.
.tables
.schema table_name
```text sqlite> .tables audit_log child docs enrollment items parent strict_users users sqlite> .schema users CREATE TABLE users( id INTEGER PRIMARY KEY, email TEXT NOT NULL UNIQUE, display_name TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')) );