The language every database understands. Not a general-purpose language like Python โ SQL is for asking questions of data: filtering, joining, grouping, and summarizing. Copy-paste examples plus live queries, running in a real database in your own browser.
Every practice box on this page runs against its own fresh, empty database โ so each example starts by creating and filling its own table.
CREATE TABLE students (
id INTEGER PRIMARY KEY,
name TEXT,
grade INTEGER
);
INSERT INTO students (id, name, grade) VALUES
(1, 'Ada', 92),
(2, 'Linus', 88),
(3, 'Grace', 95);
SELECT * FROM students; -- every column, every row
SELECT name, grade FROM students; -- just these columns
SELECT * FROM students WHERE grade >= 90; -- filter rows
SELECT * FROM students WHERE name LIKE 'A%'; -- starts with "A"
SELECT * FROM students ORDER BY grade DESC; -- highest grade first
SELECT * FROM students ORDER BY grade DESC LIMIT 1; -- just the top student
SELECT COUNT(*) FROM students; -- how many rows
SELECT AVG(grade) FROM students; -- average grade
SELECT MAX(grade), MIN(grade) FROM students;
Splits rows into buckets, then runs an aggregate function on each bucket separately.
CREATE TABLE orders (id INTEGER, customer TEXT, amount REAL);
INSERT INTO orders VALUES (1,'Sam',20), (2,'Sam',35), (3,'Ana',50);
SELECT customer, SUM(amount) FROM orders GROUP BY customer;
-- Sam: 55, Ana: 50 โ one total PER customer, not one grand total
Combines rows from two tables based on a matching column โ the whole point of having separate tables instead of one giant one.
CREATE TABLE customers (id INTEGER, name TEXT);
INSERT INTO customers VALUES (1, 'Sam'), (2, 'Ana');
CREATE TABLE orders2 (id INTEGER, customer_id INTEGER, amount REAL);
INSERT INTO orders2 VALUES (1, 1, 20), (2, 2, 50);
SELECT customers.name, orders2.amount
FROM orders2
JOIN customers ON orders2.customer_id = customers.id;
UPDATE students SET grade = 100 WHERE name = 'Ada';
DELETE FROM students WHERE grade < 60;
WHERE with UPDATE/DELETE โ leave it off and you change or erase every row in the table.SELECT * FROM students WHERE grade IS NULL; -- NOT "= NULL" โ that never matches
SELECT name, COALESCE(grade, 0) FROM students; -- replace NULL with a default value
Runs against a real in-browser SQLite database (via sql.js/WebAssembly) โ no server round-trip, same as Python and JavaScript.
CREATE TABLE students (id INTEGER, name TEXT, grade INTEGER);
INSERT INTO students VALUES
(1,'Ada',92), (2,'Linus',78), (3,'Grace',95), (4,'Sam',65);
SELECT name, grade FROM students
WHERE grade >= 80
ORDER BY grade DESC;
CREATE TABLE sales (id INTEGER, amount REAL);
INSERT INTO sales VALUES (1,20.5), (2,35.0), (3,12.25);
SELECT COUNT(*) AS num_sales, SUM(amount) AS total FROM sales;
CREATE TABLE orders (id INTEGER, customer TEXT, amount REAL);
INSERT INTO orders VALUES
(1,'Sam',20), (2,'Sam',35), (3,'Ana',10), (4,'Ana',15);
-- only show customers whose total spend is over 30
SELECT customer, SUM(amount) AS total
FROM orders
GROUP BY customer
HAVING SUM(amount) > 30;
CREATE TABLE authors (id INTEGER, name TEXT);
INSERT INTO authors VALUES (1,'Orwell'), (2,'Austen');
CREATE TABLE books (id INTEGER, title TEXT, author_id INTEGER);
INSERT INTO books VALUES (1,'1984',1), (2,'Animal Farm',1), (3,'Emma',2);
SELECT authors.name, books.title
FROM books
JOIN authors ON books.author_id = authors.id
ORDER BY authors.name, books.title;