Select all columns
Return every column from a table.
SELECT * FROM users;
Tip: Try changing table and column names to match your own database.
Smart SQL Tools for Every Database
SQL Education Hub
Practical copy-and-paste SQL examples for beginners, students, developers, and data analysts. This page covers SELECT queries, filters, joins, grouping, subqueries, date functions, string functions, CTEs, and window functions.
Use this page as a SQL cheat sheet. Most examples are easy to adapt for MySQL, PostgreSQL, SQL Server, SQLite, and Oracle.
Return every column from a table.
SELECT * FROM users;
Tip: Try changing table and column names to match your own database.
Return only the columns you need.
SELECT id, name, email FROM users;
Tip: Try changing table and column names to match your own database.
Rename a column in the result.
SELECT first_name AS name FROM users;
Tip: Try changing table and column names to match your own database.
Remove duplicate values.
SELECT DISTINCT country FROM customers;
Tip: Try changing table and column names to match your own database.
Return a small number of rows.
SELECT * FROM orders LIMIT 10;
Tip: Try changing table and column names to match your own database.
SQL Server uses TOP instead of LIMIT.
SELECT TOP 10 * FROM orders;
Tip: Try changing table and column names to match your own database.
Common row limiting syntax across dialects.
-- MySQL/PostgreSQL/SQLite
SELECT * FROM products LIMIT 10;
-- SQL Server
SELECT TOP 10 * FROM products;
-- Oracle
SELECT * FROM products FETCH FIRST 10 ROWS ONLY;
Tip: Try changing table and column names to match your own database.
Add comments to explain a query.
-- Get active users
SELECT * FROM users WHERE status = 'active';
Tip: Try changing table and column names to match your own database.
Return a fixed value.
SELECT 'Hello SQL' AS message;
Tip: Try changing table and column names to match your own database.
Create a value from existing columns.
SELECT price, quantity, price * quantity AS total FROM order_items;
Tip: Try changing table and column names to match your own database.
Filter rows by exact value.
SELECT * FROM users WHERE status = 'active';
Tip: Try changing table and column names to match your own database.
Exclude a value.
SELECT * FROM users WHERE status <> 'inactive';
Tip: Try changing table and column names to match your own database.
Find rows above a number.
SELECT * FROM products WHERE price > 100;
Tip: Try changing table and column names to match your own database.
Find values inside a range.
SELECT * FROM orders WHERE total BETWEEN 50 AND 200;
Tip: Try changing table and column names to match your own database.
Match any value from a list.
SELECT * FROM users WHERE country IN ('US', 'Canada', 'Korea');
Tip: Try changing table and column names to match your own database.
Exclude values from a list.
SELECT * FROM users WHERE role NOT IN ('admin', 'owner');
Tip: Try changing table and column names to match your own database.
Search using a pattern.
SELECT * FROM customers WHERE name LIKE '%kim%';
Tip: Try changing table and column names to match your own database.
Find text that begins with letters.
SELECT * FROM customers WHERE email LIKE 'emily%';
Tip: Try changing table and column names to match your own database.
Find text that ends with letters.
SELECT * FROM files WHERE filename LIKE '%.pdf';
Tip: Try changing table and column names to match your own database.
Find missing values.
SELECT * FROM users WHERE phone IS NULL;
Tip: Try changing table and column names to match your own database.
Find rows with a value.
SELECT * FROM users WHERE phone IS NOT NULL;
Tip: Try changing table and column names to match your own database.
All conditions must be true.
SELECT * FROM orders WHERE status = 'paid' AND total > 100;
Tip: Try changing table and column names to match your own database.
At least one condition must be true.
SELECT * FROM users WHERE city = 'Nashville' OR city = 'Atlanta';
Tip: Try changing table and column names to match your own database.
Control AND/OR logic.
SELECT * FROM users WHERE status = 'active' AND (city = 'Nashville' OR city = 'Franklin');
Tip: Try changing table and column names to match your own database.
Search text without caring about letter case.
-- PostgreSQL
SELECT * FROM users WHERE email ILIKE '%gmail%';
-- MySQL common option
SELECT * FROM users WHERE LOWER(email) LIKE '%gmail%';
Tip: Try changing table and column names to match your own database.
Sort from low to high.
SELECT * FROM products ORDER BY price ASC;
Tip: Try changing table and column names to match your own database.
Sort from high to low.
SELECT * FROM products ORDER BY price DESC;
Tip: Try changing table and column names to match your own database.
Sort by more than one column.
SELECT * FROM users ORDER BY country ASC, name ASC;
Tip: Try changing table and column names to match your own database.
Show newest or oldest rows.
SELECT * FROM orders ORDER BY created_at DESC;
Tip: Try changing table and column names to match your own database.
Sort by a computed column.
SELECT name, price * quantity AS total FROM items ORDER BY total DESC;
Tip: Try changing table and column names to match your own database.
Skip rows for pagination.
SELECT * FROM posts ORDER BY id LIMIT 10 OFFSET 20;
Tip: Try changing table and column names to match your own database.
Page 3 with 10 rows per page.
SELECT * FROM posts ORDER BY created_at DESC LIMIT 10 OFFSET 20;
Tip: Try changing table and column names to match your own database.
Return one random row.
-- PostgreSQL/SQLite
SELECT * FROM products ORDER BY RANDOM() LIMIT 1;
-- MySQL
SELECT * FROM products ORDER BY RAND() LIMIT 1;
Tip: Try changing table and column names to match your own database.
Find the newest row.
SELECT * FROM orders ORDER BY created_at DESC LIMIT 1;
Tip: Try changing table and column names to match your own database.
Find the oldest row.
SELECT * FROM orders ORDER BY created_at ASC LIMIT 1;
Tip: Try changing table and column names to match your own database.
Count all rows.
SELECT COUNT(*) AS total_users FROM users;
Tip: Try changing table and column names to match your own database.
Count unique values.
SELECT COUNT(DISTINCT country) AS country_count FROM users;
Tip: Try changing table and column names to match your own database.
Add numeric values.
SELECT SUM(total) AS revenue FROM orders;
Tip: Try changing table and column names to match your own database.
Calculate average value.
SELECT AVG(price) AS average_price FROM products;
Tip: Try changing table and column names to match your own database.
Find the smallest value.
SELECT MIN(price) AS cheapest FROM products;
Tip: Try changing table and column names to match your own database.
Find the largest value.
SELECT MAX(price) AS most_expensive FROM products;
Tip: Try changing table and column names to match your own database.
Aggregate by category.
SELECT country, COUNT(*) AS users FROM users GROUP BY country;
Tip: Try changing table and column names to match your own database.
Aggregate by more than one field.
SELECT country, status, COUNT(*) AS total FROM users GROUP BY country, status;
Tip: Try changing table and column names to match your own database.
Filter grouped results.
SELECT customer_id, COUNT(*) AS orders FROM orders GROUP BY customer_id HAVING COUNT(*) > 5;
Tip: Try changing table and column names to match your own database.
Sort grouped results.
SELECT country, COUNT(*) AS users FROM users GROUP BY country ORDER BY users DESC;
Tip: Try changing table and column names to match your own database.
Return matching rows from both tables.
SELECT users.name, orders.total
FROM users
INNER JOIN orders ON users.id = orders.user_id;
Tip: Try changing table and column names to match your own database.
Return all rows from the left table.
SELECT users.name, orders.total
FROM users
LEFT JOIN orders ON users.id = orders.user_id;
Tip: Try changing table and column names to match your own database.
Return all rows from the right table.
SELECT users.name, orders.total
FROM users
RIGHT JOIN orders ON users.id = orders.user_id;
Tip: Try changing table and column names to match your own database.
Return matched and unmatched rows from both tables.
SELECT users.name, orders.total
FROM users
FULL OUTER JOIN orders ON users.id = orders.user_id;
Tip: Try changing table and column names to match your own database.
Join a table to itself.
SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;
Tip: Try changing table and column names to match your own database.
Combine data from three related tables.
SELECT users.name, orders.id, products.name
FROM users
JOIN orders ON users.id = orders.user_id
JOIN products ON orders.product_id = products.id;
Tip: Try changing table and column names to match your own database.
Use short table names.
SELECT u.name, o.total
FROM users u
JOIN orders o ON u.id = o.user_id;
Tip: Try changing table and column names to match your own database.
Count joined records.
SELECT u.name, COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.name;
Tip: Try changing table and column names to match your own database.
Find users with no orders.
SELECT u.*
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE o.id IS NULL;
Tip: Try changing table and column names to match your own database.
Join through a bridge table.
SELECT s.name, c.title
FROM students s
JOIN student_courses sc ON s.id = sc.student_id
JOIN courses c ON sc.course_id = c.id;
Tip: Try changing table and column names to match your own database.
Filter using another query.
SELECT * FROM products WHERE price > (SELECT AVG(price) FROM products);
Tip: Try changing table and column names to match your own database.
Show a calculated value from another query.
SELECT name, (SELECT COUNT(*) FROM orders WHERE orders.user_id = users.id) AS order_count FROM users;
Tip: Try changing table and column names to match your own database.
Query a temporary result set.
SELECT country, total_users FROM (SELECT country, COUNT(*) AS total_users FROM users GROUP BY country) t;
Tip: Try changing table and column names to match your own database.
Check whether related rows exist.
SELECT * FROM users u WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);
Tip: Try changing table and column names to match your own database.
Find rows without related records.
SELECT * FROM users u WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);
Tip: Try changing table and column names to match your own database.
A subquery that uses the outer query.
SELECT * FROM orders o WHERE total > (SELECT AVG(total) FROM orders WHERE user_id = o.user_id);
Tip: Try changing table and column names to match your own database.
Find products above average price.
SELECT * FROM products WHERE price > (SELECT AVG(price) FROM products);
Tip: Try changing table and column names to match your own database.
Find emails used more than once.
SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1;
Tip: Try changing table and column names to match your own database.
Find each customer's largest order.
SELECT * FROM orders o WHERE total = (SELECT MAX(total) FROM orders WHERE user_id = o.user_id);
Tip: Try changing table and column names to match your own database.
Example pattern for duplicate cleanup.
DELETE FROM users
WHERE id NOT IN (
SELECT MIN(id)
FROM users
GROUP BY email
);
Tip: Try changing table and column names to match your own database.
Add one record.
INSERT INTO users (name, email) VALUES ('Emily', 'emily@example.com');
Tip: Try changing table and column names to match your own database.
Add several records.
INSERT INTO users (name, email) VALUES ('Amy', 'amy@example.com'), ('John', 'john@example.com');
Tip: Try changing table and column names to match your own database.
Copy rows from another table.
INSERT INTO archived_orders SELECT * FROM orders WHERE created_at < '2024-01-01';
Tip: Try changing table and column names to match your own database.
Modify one record.
UPDATE users SET status = 'active' WHERE id = 1;
Tip: Try changing table and column names to match your own database.
Modify many records.
UPDATE products SET discontinued = true WHERE stock = 0;
Tip: Try changing table and column names to match your own database.
Update using another table.
-- MySQL
UPDATE users u
JOIN orders o ON u.id = o.user_id
SET u.last_order_date = o.created_at;
Tip: Try changing table and column names to match your own database.
Remove one record.
DELETE FROM users WHERE id = 1;
Tip: Try changing table and column names to match your own database.
Remove matching rows.
DELETE FROM logs WHERE created_at < '2024-01-01';
Tip: Try changing table and column names to match your own database.
Delete duplicate rows carefully.
DELETE FROM users WHERE id NOT IN (SELECT MIN(id) FROM users GROUP BY email);
Tip: Try changing table and column names to match your own database.
Insert or update if already exists.
-- PostgreSQL
INSERT INTO users (id, email) VALUES (1, 'a@example.com')
ON CONFLICT (id) DO UPDATE SET email = EXCLUDED.email;
Tip: Try changing table and column names to match your own database.
Return today's date.
SELECT CURRENT_DATE;
Tip: Try changing table and column names to match your own database.
Return current date and time.
SELECT CURRENT_TIMESTAMP;
Tip: Try changing table and column names to match your own database.
Add days to a date.
-- PostgreSQL
SELECT CURRENT_DATE + INTERVAL '7 days';
-- MySQL
SELECT DATE_ADD(CURRENT_DATE, INTERVAL 7 DAY);
Tip: Try changing table and column names to match your own database.
Subtract days from a date.
-- PostgreSQL
SELECT CURRENT_DATE - INTERVAL '7 days';
-- MySQL
SELECT DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY);
Tip: Try changing table and column names to match your own database.
Find days between dates.
-- PostgreSQL
SELECT DATE '2026-05-09' - DATE '2026-05-01' AS days;
-- MySQL
SELECT DATEDIFF('2026-05-09', '2026-05-01') AS days;
Tip: Try changing table and column names to match your own database.
Get year from a date.
SELECT EXTRACT(YEAR FROM created_at) AS year FROM orders;
Tip: Try changing table and column names to match your own database.
Get month from a date.
SELECT EXTRACT(MONTH FROM created_at) AS month FROM orders;
Tip: Try changing table and column names to match your own database.
Format dates by dialect.
-- MySQL
SELECT DATE_FORMAT(created_at, '%Y-%m-%d') FROM orders;
-- PostgreSQL
SELECT TO_CHAR(created_at, 'YYYY-MM-DD') FROM orders;
Tip: Try changing table and column names to match your own database.
Find recent records.
SELECT * FROM orders WHERE created_at >= CURRENT_DATE - INTERVAL '7 days';
Tip: Try changing table and column names to match your own database.
Monthly totals.
SELECT DATE_TRUNC('month', created_at) AS month, COUNT(*) FROM orders GROUP BY month ORDER BY month;
Tip: Try changing table and column names to match your own database.
Join text values.
-- PostgreSQL/SQLite
SELECT first_name || ' ' || last_name AS full_name FROM users;
-- MySQL
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM users;
Tip: Try changing table and column names to match your own database.
Convert text to uppercase.
SELECT UPPER(name) FROM users;
Tip: Try changing table and column names to match your own database.
Convert text to lowercase.
SELECT LOWER(email) FROM users;
Tip: Try changing table and column names to match your own database.
Remove spaces from both ends.
SELECT TRIM(name) FROM users;
Tip: Try changing table and column names to match your own database.
Get part of a string.
SELECT SUBSTRING(name FROM 1 FOR 3) FROM users;
Tip: Try changing table and column names to match your own database.
Replace part of a string.
SELECT REPLACE(phone, '-', '') FROM users;
Tip: Try changing table and column names to match your own database.
Count characters.
SELECT LENGTH(name) FROM users;
Tip: Try changing table and column names to match your own database.
Split text by delimiter.
-- PostgreSQL
SELECT SPLIT_PART(email, '@', 2) AS domain FROM users;
Tip: Try changing table and column names to match your own database.
Find text position.
-- PostgreSQL
SELECT POSITION('@' IN email) FROM users;
-- MySQL
SELECT LOCATE('@', email) FROM users;
Tip: Try changing table and column names to match your own database.
Convert number to string.
SELECT CAST(id AS VARCHAR) FROM users;
Tip: Try changing table and column names to match your own database.
Use a named temporary result.
WITH active_users AS (
SELECT * FROM users WHERE status = 'active'
)
SELECT * FROM active_users;
Tip: Try changing table and column names to match your own database.
Generate hierarchical or repeated results.
WITH RECURSIVE numbers AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1 FROM numbers WHERE n < 10
)
SELECT * FROM numbers;
Tip: Try changing table and column names to match your own database.
Number rows in order.
SELECT name, ROW_NUMBER() OVER (ORDER BY created_at) AS row_num FROM users;
Tip: Try changing table and column names to match your own database.
Rank rows with ties.
SELECT name, score, RANK() OVER (ORDER BY score DESC) AS rank FROM students;
Tip: Try changing table and column names to match your own database.
Calculate cumulative sum.
SELECT order_date, total,
SUM(total) OVER (ORDER BY order_date) AS running_total
FROM orders;
Tip: Try changing table and column names to match your own database.