SQL is a small language with a large reach. Five statements cover most day-to-day work: CREATE TABLE, INSERT, SELECT, UPDATE and DELETE.
Learning objectives
- Create tables with sensible types and constraints.
- Insert, read, update and delete rows.
- Filter with
WHERE, sort withORDER BYand limit results. - Avoid the two classic accidents: updating or deleting everything.
1. CREATE TABLE
DROP TABLE IF EXISTS books;
CREATE TABLE books (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
author TEXT NOT NULL,
price INTEGER DEFAULT 0,
category TEXT,
isbn TEXT UNIQUE,
published TEXT
);
SQLite types are flexible: INTEGER, TEXT, REAL, BLOB, NULL. Dates are usually stored as ISO text (2026-10-21) or Unix timestamps.
2. INSERT
INSERT INTO books (title, author, price, category, published) VALUES
('The Pragmatic Programmer', 'Hunt & Thomas', 30000, 'Programming', '1999-10-30'),
('Clean Code', 'Robert C. Martin', 35000, 'Programming', '2008-08-01'),
('Atomic Habits', 'James Clear', 14000, 'Self-help', '2018-10-16');
Name the columns explicitly. A table change later will not silently shift your values.
3. SELECT
SELECT * FROM books;
SELECT title, price FROM books;
SELECT title, author, price
FROM books
WHERE category = 'Programming'
ORDER BY price DESC
LIMIT 2;
Execution order is roughly FROM → WHERE → SELECT → ORDER BY → LIMIT. That is why an alias defined in SELECT cannot always be used in WHERE.
Filters worth knowing:
WHERE price >= 20000
WHERE price BETWEEN 10000 AND 30000
WHERE category IN ('Programming', 'Self-help')
WHERE title LIKE '%Code%' -- % = any characters, _ = one character
WHERE isbn IS NULL -- never use = NULL
4. UPDATE
UPDATE books
SET price = 32000
WHERE id = 2;
Without WHERE, every row changes. Before running an update, run the same WHERE in a SELECT and confirm it matches exactly the rows you expect.
5. DELETE
DELETE FROM books WHERE id = 3;
DELETE FROM books; empties the table. There is no undo outside a transaction.
6. Aggregates
SELECT COUNT(*) AS total FROM books;
SELECT AVG(price) AS average_price FROM books;
SELECT category, COUNT(*) AS n, MAX(price) AS dearest
FROM books
GROUP BY category;
COUNT, SUM, AVG, MIN and MAX collapse many rows into one. With GROUP BY, they produce one row per group.
7. Practical habits
- Use a
WHEREclause in everyUPDATEandDELETE. - Prefer explicit column lists over
SELECT *in application queries. - Keep a
schema.sqlin the repository so a fresh database can be rebuilt in one command. - Run queries in a scratch database first; production is not a playground.
Practice
Create the books table and answer the queries in the assignment. Keep the file so later lessons can reuse it.