MySQL Cheat Sheet

A quick lookup for the MySQL syntax you use most — database and table commands, data types, querying, joins, aggregation, indexes, and user management. Each section keeps the syntax terse so you can find and copy what you need fast.

Note: examples use standard MySQL 8.x syntax. A few features (window functions, CTEs) require 8.0+, and some behavior differs in MariaDB.


Database Commands

TaskCommand
List databasesSHOW DATABASES;
Create a databaseCREATE DATABASE mydb;
Use a databaseUSE mydb;
Delete a databaseDROP DATABASE mydb;
Show current databaseSELECT DATABASE();

Table Commands

TaskCommand
List tablesSHOW TABLES;
Describe a tableDESCRIBE users;
Show create statementSHOW CREATE TABLE users;
Create a tableCREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(100));
Rename a tableRENAME TABLE old_name TO new_name;
Delete a tableDROP TABLE users;
Empty a table (keep structure)TRUNCATE TABLE users;

Altering Tables

TaskCommand
Add a columnALTER TABLE users ADD email VARCHAR(255);
Modify a columnALTER TABLE users MODIFY name VARCHAR(200);
Rename a columnALTER TABLE users RENAME COLUMN name TO full_name;
Drop a columnALTER TABLE users DROP COLUMN email;
Add an indexALTER TABLE users ADD INDEX (email);

Common Data Types

TypeDescriptionExample
INTIntegerage INT
BIGINTLarge integerviews BIGINT
DECIMAL(p,s)Exact decimal (money)price DECIMAL(10,2)
FLOAT / DOUBLEApproximate floatratio DOUBLE
VARCHAR(n)Variable-length stringname VARCHAR(100)
CHAR(n)Fixed-length stringcode CHAR(3)
TEXTLong textbio TEXT
BOOLEANTrue/false (alias for TINYINT(1))active BOOLEAN
DATEDate onlydob DATE
DATETIMEDate and timecreated_at DATETIME
TIMESTAMPAuto-updating timestampupdated_at TIMESTAMP
JSONJSON data (5.7+)meta JSON
ENUM(...)One value from a liststatus ENUM('on','off')

Querying Data (SELECT)

TaskCommand
Select all columnsSELECT * FROM users;
Select specific columnsSELECT id, name FROM users;
Filter rowsSELECT * FROM users WHERE age > 18;
Sort resultsSELECT * FROM users ORDER BY name ASC;
Limit resultsSELECT * FROM users LIMIT 10;
PaginationSELECT * FROM users LIMIT 10 OFFSET 20;
Remove duplicatesSELECT DISTINCT country FROM users;
Pattern matchSELECT * FROM users WHERE name LIKE 'A%';
Match a setSELECT * FROM users WHERE id IN (1,2,3);
RangeSELECT * FROM users WHERE age BETWEEN 18 AND 30;
Null checkSELECT * FROM users WHERE email IS NULL;

Inserting, Updating & Deleting

TaskCommand
Insert a rowINSERT INTO users (name) VALUES ('Ana');
Insert multiple rowsINSERT INTO users (name) VALUES ('A'),('B');
Update rowsUPDATE users SET active = 1 WHERE id = 5;
Delete rowsDELETE FROM users WHERE id = 5;
Insert or update (upsert)INSERT INTO users (id,name) VALUES (1,'A') ON DUPLICATE KEY UPDATE name='A';

Always use a WHERE clause with UPDATE and DELETE, or you'll change every row in the table.


Joins

JoinMeaningCommand
INNER JOINOnly matching rows in both tablesSELECT * FROM a INNER JOIN b ON a.id = b.a_id;
LEFT JOINAll rows from left, matches from rightSELECT * FROM a LEFT JOIN b ON a.id = b.a_id;
RIGHT JOINAll rows from right, matches from leftSELECT * FROM a RIGHT JOIN b ON a.id = b.a_id;
CROSS JOINEvery combination (cartesian)SELECT * FROM a CROSS JOIN b;

MySQL has no built-in FULL OUTER JOIN — emulate it by UNION-ing a LEFT JOIN and a RIGHT JOIN.


Aggregation & Grouping

TaskCommand
Count rowsSELECT COUNT(*) FROM users;
Sum a columnSELECT SUM(amount) FROM orders;
AverageSELECT AVG(price) FROM products;
Min / MaxSELECT MIN(age), MAX(age) FROM users;
Group bySELECT country, COUNT(*) FROM users GROUP BY country;
Filter groups... GROUP BY country HAVING COUNT(*) > 5;

Use WHERE to filter rows before grouping and HAVING to filter after grouping.


Indexes & Keys

TaskCommand
Create an indexCREATE INDEX idx_email ON users (email);
Unique indexCREATE UNIQUE INDEX idx_email ON users (email);
Composite indexCREATE INDEX idx_name_age ON users (name, age);
List indexesSHOW INDEX FROM users;
Drop an indexDROP INDEX idx_email ON users;
Add a foreign keyALTER TABLE orders ADD FOREIGN KEY (user_id) REFERENCES users(id);

User & Permission Management

TaskCommand
Create a userCREATE USER 'app'@'localhost' IDENTIFIED BY 'pass';
Grant privilegesGRANT ALL ON mydb.* TO 'app'@'localhost';
Grant read-onlyGRANT SELECT ON mydb.* TO 'app'@'localhost';
Apply changesFLUSH PRIVILEGES;
Show grantsSHOW GRANTS FOR 'app'@'localhost';
Revoke privilegesREVOKE ALL ON mydb.* FROM 'app'@'localhost';
Delete a userDROP USER 'app'@'localhost';

Backup & Restore (CLI)

TaskCommand
Back up a databasemysqldump -u root -p mydb > backup.sql
Back up all databasesmysqldump -u root -p --all-databases > all.sql
Restore a databasemysql -u root -p mydb < backup.sql

Golden Rules

  1. Filter your writes — never run UPDATE or DELETE without a WHERE clause unless you truly mean every row.
  2. Index what you filter and join on — indexes speed up reads dramatically but slow down writes, so index deliberately.
  3. Use DECIMAL for moneyFLOAT/DOUBLE introduce rounding errors.
  4. Prefer parameterized queries — never concatenate user input into SQL; it's the root cause of SQL injection.
  5. TRUNCATEDELETETRUNCATE is faster, resets auto-increment, and can't be rolled back the same way; DELETE is row-by-row and transactional.

Frequently Asked Questions

What is the difference between DELETE and TRUNCATE in MySQL? DELETE removes rows one at a time and can use a WHERE clause and be rolled back within a transaction. TRUNCATE empties the whole table quickly, resets the auto-increment counter, and can't be filtered.

What is the difference between WHERE and HAVING? WHERE filters individual rows before grouping, while HAVING filters grouped results after GROUP BY. Use HAVING when your condition involves an aggregate like COUNT().

What's the difference between CHAR and VARCHAR? CHAR(n) is fixed-length and pads with spaces, which suits short, uniform values like country codes. VARCHAR(n) stores only the characters used, which is better for variable-length text.

How do I do an upsert (insert or update) in MySQL? Use INSERT ... ON DUPLICATE KEY UPDATE. If a row with the same primary key or unique index exists, MySQL updates it instead of inserting a duplicate.

Does MySQL support FULL OUTER JOIN? Not natively. You emulate it by combining a LEFT JOIN and a RIGHT JOIN with UNION.

When should I add an index? Add indexes to columns you frequently filter (WHERE), join on, or sort by. Avoid over-indexing, since each index adds overhead to inserts and updates.

Last Updated on Jul 13, 2026