Install SQLite, load a real dataset, and write queries that actually answer questions. You'll filter, sort, and slice data before this session ends.
A set of working queries against a real sales database — find top customers, filter orders by date range, sort products by revenue. By the end, SQL will feel like asking questions in English.
SQLite runs entirely on your laptop — no server, no account, no configuration. It's used inside every iPhone, Android, and most desktop applications. Perfect for learning.
Download DB Browser for SQLite from sqlitebrowser.org. It's free and gives you a visual interface. Install it, then open it.
Now grab the practice database. Create a file called sales.db — we'll populate it with this SQL:
CREATE TABLE customers ( id INTEGER PRIMARY KEY, name TEXT, city TEXT, segment TEXT ); CREATE TABLE orders ( id INTEGER PRIMARY KEY, customer_id INTEGER, order_date TEXT, amount REAL, status TEXT ); INSERT INTO customers VALUES (1,'Acme Corp','Denver','Enterprise'), (2,'BetaCo','Austin','SMB'), (3,'Gamma LLC','New York','Enterprise'), (4,'Delta Inc','Chicago','SMB'), (5,'Epsilon','Denver','Startup'); INSERT INTO orders VALUES (1,1,'2025-01-15',12500.00,'completed'), (2,2,'2025-01-22',3200.00,'completed'), (3,1,'2025-02-08',8900.00,'completed'), (4,3,'2025-02-14',21000.00,'completed'), (5,4,'2025-03-01',1500.00,'pending'), (6,5,'2025-03-10',4700.00,'completed');
In DB Browser: click Open Database → create a new file → paste that SQL into the Execute SQL tab → click Run. You now have a real database with real data.
Every SQL query you'll ever write starts with SELECT (what columns you want) and FROM (which table). That's it.
-- Get every column from customers SELECT * FROM customers; -- Get only the name and city columns SELECT name, city FROM customers; -- Rename a column in the output with AS SELECT name AS customer_name, city AS location FROM customers;
The * means "all columns." It's fine for exploring — in production code, always name your columns explicitly so you know exactly what you're getting.
WHERE filters which rows come back. It's the most powerful clause in basic SQL — think of it as the filter in a spreadsheet, but with full logical operators.
-- Customers in Denver only SELECT * FROM customers WHERE city = 'Denver'; -- Orders over $5,000 SELECT * FROM orders WHERE amount > 5000; -- Completed orders over $5,000 (AND = both conditions) SELECT * FROM orders WHERE status = 'completed' AND amount > 5000; -- Orders from Denver OR Chicago customers (OR = either) SELECT * FROM customers WHERE city = 'Denver' OR city = 'Chicago'; -- Shorthand for OR on the same column: IN SELECT * FROM customers WHERE city IN ('Denver', 'Chicago'); -- Orders in a date range (dates stored as text, comparison still works) SELECT * FROM orders WHERE order_date BETWEEN '2025-01-01' AND '2025-02-28';
Text comparisons are case-sensitive in SQLite. 'Denver' and 'denver' are different values. Use LOWER(city) = 'denver' if your data is inconsistent.
Sort your results and limit how many rows come back. Essential for "show me the top 10" queries.
-- Orders sorted largest to smallest SELECT * FROM orders ORDER BY amount DESC; -- Top 3 orders by amount SELECT * FROM orders ORDER BY amount DESC LIMIT 3; -- Customers sorted alphabetically SELECT name, city FROM customers ORDER BY name ASC; -- Most recent completed orders, top 5 SELECT id, order_date, amount FROM orders WHERE status = 'completed' ORDER BY order_date DESC LIMIT 5;
SQL clause order matters: SELECT → FROM → WHERE → ORDER BY → LIMIT. You can't put LIMIT before WHERE. The database executes them in a specific order even if you could write them differently.
Day 2 is where SQL gets powerful — combining tables and calculating totals, averages, and counts across real data.
Day 2: JOINs and GROUP BYBefore moving on, make sure you can answer these without looking: