MySQL Cheat Sheet
A complete reference of MySQL syntax with 65 interactive examples. Copy code snippets or click “Try It” to run them directly in your browser.
Creating & Modifying Tables
CREATE TABLE
Create a new table with columns and constraints.
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;Tip: Use InnoDB engine for transaction support and foreign keys.
CREATE TABLE IF NOT EXISTS
Create a table only if it does not already exist.
CREATE TABLE IF NOT EXISTS logs (
id INT AUTO_INCREMENT PRIMARY KEY,
message TEXT,
level VARCHAR(20) DEFAULT 'info'
);ALTER TABLE ADD
Add a new column to an existing table.
ALTER TABLE users ADD COLUMN phone VARCHAR(20);ALTER TABLE MODIFY
Change a column type or constraints.
ALTER TABLE users MODIFY COLUMN name VARCHAR(500) NOT NULL;Tip: Use MODIFY to change type, CHANGE to also rename.
ALTER TABLE RENAME
Rename a table or column.
ALTER TABLE users CHANGE name full_name VARCHAR(255) NOT NULL;DROP TABLE
Delete a table and all its data.
DROP TABLE IF EXISTS temp_data;Tip: Use IF EXISTS to avoid errors when the table does not exist.
CREATE INDEX
Create an index to speed up queries.
CREATE INDEX idx_users_email ON users(email);Tip: MySQL supports B-tree, Hash, Full-text, and Spatial indexes.
CREATE VIEW
Create a virtual table based on a SELECT query.
CREATE VIEW active_users AS
SELECT id, name, email FROM users
WHERE created_at > DATE_SUB(NOW(), INTERVAL 30 DAY);CREATE DATABASE
Create a new database.
CREATE DATABASE IF NOT EXISTS myapp
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;Tip: Use utf8mb4 for full Unicode support including emojis.
Adding & Changing Data
INSERT
Add new rows to a table.
INSERT INTO users (name, email)
VALUES ('Dave Wilson', 'dave@example.com');
SELECT * FROM users WHERE name = 'Dave Wilson';INSERT Multiple Rows
Insert multiple rows in a single statement.
INSERT INTO products (name, category, price, stock) VALUES
('Headphones', 'Electronics', 149.99, 100),
('Webcam', 'Electronics', 89.99, 60);
SELECT * FROM products WHERE name IN ('Headphones', 'Webcam');UPDATE
Modify existing rows in a table.
UPDATE orders SET status = 'shipped'
WHERE id = 3;
SELECT * FROM orders WHERE id = 3;Tip: Always use WHERE to avoid updating all rows.
DELETE
Remove rows from a table.
DELETE FROM orders WHERE status = 'pending';
SELECT * FROM orders;Tip: Always use WHERE unless you want to delete all rows.
REPLACE
Insert or replace a row if it exists.
REPLACE INTO users (id, name, email)
VALUES (1, 'Alice Updated', 'alice.new@example.com');
SELECT * FROM users WHERE id = 1;Tip: REPLACE deletes then inserts; use ON DUPLICATE KEY for updates.
INSERT ON DUPLICATE KEY
Insert or update on primary key/unique conflict.
INSERT INTO users (id, name, email)
VALUES (2, 'Bob Updated', 'bob.new@example.com')
ON DUPLICATE KEY UPDATE
name = VALUES(name),
email = VALUES(email);
SELECT * FROM users WHERE id = 2;Tip: VALUES() refers to the values that would have been inserted.
TRUNCATE
Quickly remove all rows from a table.
-- TRUNCATE is faster than DELETE for removing all rows
-- TRUNCATE TABLE logs;Tip: TRUNCATE resets AUTO_INCREMENT; DELETE does not.
LOAD DATA
Bulk import data from a file.
-- Import from CSV
-- LOAD DATA INFILE '/tmp/users.csv'
-- INTO TABLE users
-- FIELDS TERMINATED BY ','
-- ENCLOSED BY '"'
-- LINES TERMINATED BY '\n'
-- IGNORE 1 ROWS;Tip: Use LOCAL INFILE for client-side files.
Querying Data
SELECT
Retrieve data from one or more tables.
SELECT name, email FROM users;SELECT *
Select all columns from a table.
SELECT * FROM products;Tip: Avoid SELECT * in production; specify needed columns.
WHERE
Filter rows based on conditions.
SELECT * FROM orders WHERE price > 50 AND status = 'completed';ORDER BY
Sort results by one or more columns.
SELECT * FROM products ORDER BY price DESC;LIMIT & OFFSET
Limit the number of results and skip rows.
SELECT * FROM products ORDER BY price DESC LIMIT 3 OFFSET 1;Tip: MySQL also supports LIMIT offset, count syntax.
GROUP BY
Group rows by column values for aggregation.
SELECT status, COUNT(*) as count, SUM(price) as total
FROM orders GROUP BY status;HAVING
Filter groups after GROUP BY (like WHERE for groups).
SELECT user_id, COUNT(*) as order_count
FROM orders
GROUP BY user_id
HAVING COUNT(*) > 1;DISTINCT
Return only unique values.
SELECT DISTINCT category FROM products;INNER JOIN
Return rows where there is a match in both tables.
SELECT users.name, orders.product, orders.price
FROM orders
INNER JOIN users ON orders.user_id = users.id;LEFT JOIN
Return all rows from left table, with matches from right.
SELECT users.name, orders.product
FROM users
LEFT JOIN orders ON users.id = orders.user_id;Tip: Unmatched right table columns will be NULL.
Subquery
Use a query inside another query.
SELECT * FROM users
WHERE id IN (SELECT user_id FROM orders WHERE price > 100);CTE (WITH clause)
Define a temporary named result set (MySQL 8.0+).
WITH high_value_orders AS (
SELECT user_id, SUM(price) as total
FROM orders
GROUP BY user_id
HAVING total > 100
)
SELECT users.name, high_value_orders.total
FROM high_value_orders
JOIN users ON users.id = high_value_orders.user_id;Tip: CTEs require MySQL 8.0 or later.
UNION
Combine results from multiple SELECT statements.
SELECT name, 'user' as type FROM users
UNION ALL
SELECT name, 'product' as type FROM products;Tip: UNION removes duplicates; UNION ALL keeps them.
Window Functions
Perform calculations across related rows (MySQL 8.0+).
SELECT name, price,
ROW_NUMBER() OVER (ORDER BY price DESC) as row_rank,
SUM(price) OVER () as total
FROM products;Tip: Window functions require MySQL 8.0 or later.
Built-in Functions
COUNT
Count the number of rows.
SELECT COUNT(*) as total_orders FROM orders;SUM & AVG
Calculate the sum or average of a column.
SELECT
SUM(price) as total_revenue,
AVG(price) as avg_order_value
FROM orders;MIN & MAX
Find the minimum or maximum value.
SELECT MIN(price) as cheapest, MAX(price) as most_expensive
FROM products;COALESCE / IFNULL
Return the first non-NULL value.
SELECT name, COALESCE(email, 'no email') as email
FROM users;Tip: IFNULL is MySQL-specific; COALESCE is standard SQL.
NULLIF
Return NULL if two values are equal.
SELECT name, NULLIF(stock, 0) as stock_or_null
FROM products;Tip: Useful for avoiding division by zero: x / NULLIF(y, 0)
CASE
Conditional logic in SQL (like if/else).
SELECT product, price,
CASE
WHEN price > 500 THEN 'expensive'
WHEN price > 100 THEN 'moderate'
ELSE 'affordable'
END as price_tier
FROM orders;IF
Simple conditional (MySQL-specific).
SELECT name, stock,
IF(stock > 0, 'In Stock', 'Out of Stock') as availability
FROM products;Tip: IF is simpler than CASE for two-way conditions.
String Functions
Manipulate text values.
SELECT
UPPER(name) as uppercase,
LENGTH(name) as name_length,
SUBSTRING_INDEX(email, '@', 1) as username
FROM users;Date Functions
Work with dates and times.
SELECT
NOW() as current_time,
CURDATE() as today,
DATE_ADD(CURDATE(), INTERVAL 7 DAY) as next_week,
YEAR(NOW()) as current_year;JSON Functions
Extract and manipulate JSON data (MySQL 5.7+).
SELECT JSON_EXTRACT('{"name": "Alice", "age": 30}', '$.name') as name;Tip: Use ->> for unquoted text extraction.
GROUP_CONCAT
Concatenate values from multiple rows.
SELECT user_id,
GROUP_CONCAT(product SEPARATOR ', ') as products
FROM orders
GROUP BY user_id;Tip: Default max length is 1024; increase with group_concat_max_len.
FIND_IN_SET
Find position of string in comma-separated list.
SELECT FIND_IN_SET('b', 'a,b,c,d') as position;Tip: Returns 0 if not found, position (1-based) if found.
Data Rules & Constraints
PRIMARY KEY
Uniquely identify each row in a table.
CREATE TABLE employees (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
department_id INT
);Tip: AUTO_INCREMENT only works with integer primary keys.
FOREIGN KEY
Link to a row in another table.
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);Tip: Requires InnoDB engine. ON DELETE options: CASCADE, SET NULL, RESTRICT.
UNIQUE
Ensure all values in a column are different.
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) UNIQUE,
username VARCHAR(100) UNIQUE
);NOT NULL
Prevent NULL values in a column.
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
price DECIMAL(10,2) NOT NULL
);DEFAULT
Set a default value when none is provided.
CREATE TABLE logs (
id INT AUTO_INCREMENT PRIMARY KEY,
message TEXT,
level VARCHAR(20) DEFAULT 'info',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);Tip: Use ON UPDATE CURRENT_TIMESTAMP for auto-updating timestamps.
CHECK
Validate data against a condition (MySQL 8.0.16+).
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
price DECIMAL(10,2) CHECK (price > 0),
stock INT CHECK (stock >= 0)
);Tip: CHECK constraints are enforced in MySQL 8.0.16+.
ENUM
Restrict column to predefined values.
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
status ENUM('pending', 'processing', 'shipped', 'delivered') DEFAULT 'pending'
);Tip: ENUM values are stored as integers internally.
Transactions
START TRANSACTION
Start a new transaction.
START TRANSACTION;
INSERT INTO users (name, email) VALUES ('Test', 'test@example.com');
-- Changes are not visible to other connections yetTip: MySQL defaults to autocommit=1; transactions disable it temporarily.
COMMIT
Save all changes made in the transaction.
START TRANSACTION;
INSERT INTO users (name, email) VALUES ('Test', 'test@example.com');
COMMIT;
SELECT * FROM users WHERE name = 'Test';ROLLBACK
Undo all changes made in the transaction.
START TRANSACTION;
DELETE FROM users;
ROLLBACK;
-- Users table is unchanged
SELECT * FROM users;SAVEPOINT
Create a point to rollback to within a transaction.
START TRANSACTION;
INSERT INTO users (name, email) VALUES ('A', 'a@test.com');
SAVEPOINT my_savepoint;
INSERT INTO users (name, email) VALUES ('B', 'b@test.com');
ROLLBACK TO SAVEPOINT my_savepoint;
COMMIT;
-- Only user 'A' was inserted
SELECT * FROM users WHERE email LIKE '%test.com';LOCK TABLES
Explicitly lock tables.
-- Lock for reading (others can read but not write)
-- LOCK TABLES users READ;
-- SELECT * FROM users;
-- UNLOCK TABLES;Tip: For row-level locking, use SELECT ... FOR UPDATE instead.
SELECT FOR UPDATE
Lock selected rows for update.
-- Lock specific rows
-- START TRANSACTION;
-- SELECT * FROM orders WHERE id = 1 FOR UPDATE;
-- UPDATE orders SET status = 'processing' WHERE id = 1;
-- COMMIT;Tip: SKIP LOCKED (MySQL 8.0+) skips locked rows - great for queues.
Utilities & Advanced
SHOW Commands
Display database metadata.
SHOW TABLES;DESCRIBE
Show table structure.
DESCRIBE users;EXPLAIN
Show query execution plan.
EXPLAIN SELECT * FROM orders WHERE user_id = 1;Tip: EXPLAIN ANALYZE (MySQL 8.0.18+) shows actual execution time.
OPTIMIZE TABLE
Reclaim space and defragment table.
-- Reclaim space after many DELETEs
-- OPTIMIZE TABLE orders;Tip: For InnoDB, this rebuilds the table and updates statistics.
LIKE Pattern Matching
Match strings with wildcards.
SELECT * FROM users WHERE email LIKE '%@example.com';Tip: LIKE is case-insensitive for non-binary strings.
REGEXP
Match patterns using regular expressions.
SELECT * FROM users WHERE email REGEXP '^[a-z]+@example\.com$';Tip: REGEXP is case-insensitive by default; use BINARY for case-sensitive.
Full-Text Search
Search text columns efficiently.
-- Create fulltext index
-- ALTER TABLE products ADD FULLTEXT(name, category);
-- Natural language search
-- SELECT * FROM products
-- WHERE MATCH(name) AGAINST('laptop');Tip: Supports natural language, boolean, and query expansion modes.
User Variables
Store values in session variables.
SET @total = 0;
SELECT @total := @total + price as running_total
FROM orders
ORDER BY id;Tip: User variables persist for the session.
LAST_INSERT_ID
Get the last auto-increment value.
INSERT INTO users (name, email) VALUES ('New User', 'new@example.com');
SELECT LAST_INSERT_ID() as new_user_id;Tip: Returns the ID for the current connection only.