MySQL Alter Table - Drop Column
Columns that are no longer used, like a fax number nobody fills in, make a table harder to understand and waste space. ALTER TABLE … DROP COLUMN removes a column and all the data in it. This tutorial shows how, and what to check first so nothing else breaks.
1. Syntax
ALTER TABLE table_name DROP [COLUMN] column_name [, DROP [COLUMN] column_name ...];
DROP COLUMN deletes the column's definition and all the values stored in it.2. Dropping a Column
ALTER TABLE students DROP COLUMN pager;
Query OK, 0 rows affected
Records: 0 Duplicates: 0 Warnings: 0
SHOW COLUMNS FROM students;
Result: 6 rows
| Field | Type | Null | Key |
|---|---|---|---|
| id | int | NO | PRI |
| name | varchar(40) | NO | MUL |
| fax | varchar(15) | YES | |
| varchar(60) | YES | ||
| age | int | YES | |
| course_id | int | YES | MUL |
3. Dropping Several Columns
Combine several DROP clauses in one statement so the table is changed only once. First let's add two throw-away columns:
ALTER TABLE students ADD COLUMN temp1 INT, ADD COLUMN temp2 INT;
ALTER TABLE students DROP COLUMN temp1, DROP COLUMN temp2;
SHOW COLUMNS FROM students LIKE 'temp%';
Result: Empty set (0 rows)
| Field | Type | Null | Key | Default | Extra |
|---|---|---|---|---|---|
| No rows | |||||
4. Columns Other Objects Depend On
Before dropping a column, find out what uses it. Each kind of dependency behaves differently.
Indexes
If the column is part of an index, MySQL removes it from the index (or drops the index if it was the only column):
ALTER TABLE students ADD COLUMN phone VARCHAR(15), ADD INDEX idx_phone (phone);
ALTER TABLE students DROP COLUMN phone;
SHOW INDEX FROM students; -- idx_phone is gone
Result: 4 rows
| Key_name | Seq_in_index | Column_name |
|---|---|---|
| PRIMARY | 1 | id |
| idx_name_email | 1 | name |
| idx_name_email | 2 | |
| fk_course | 1 | course_id |
Foreign keys
A column used in a foreign key can't be dropped until the constraint is dropped:
ALTER TABLE students DROP COLUMN course_id;
ERROR 1828 (HY000): Cannot drop column 'course_id': needed in a foreign key constraint 'fk_course'
ALTER TABLE students DROP FOREIGN KEY fk_course;
ALTER TABLE students DROP COLUMN course_id;
SHOW COLUMNS FROM students LIKE 'course%';
Result: Empty set (0 rows)
| Field | Type | Null | Key | Default | Extra |
|---|---|---|---|---|---|
| No rows | |||||
CHECK constraints
A CHECK constraint that refers only to the dropped column is removed with it. If it refers to several columns, the drop fails until you drop the constraint:
ALTER TABLE students DROP COLUMN age;
SELECT constraint_name FROM information_schema.check_constraints WHERE constraint_schema = 'college';
Result: Empty set (0 rows)
| CONSTRAINT_NAME |
|---|
| No rows |
Views
Views are not checked. The view keeps the old column name and breaks:
ALTER TABLE students DROP COLUMN fax;
SELECT * FROM student_contacts;
Query OK, 0 rows affected
Records: 0 Duplicates: 0 Warnings: 0
ERROR 1356 (HY000): View 'college.student_contacts' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
CREATE OR REPLACE VIEW student_contacts AS SELECT name, email FROM students;
SELECT * FROM student_contacts;
Result: 3 rows
| name | |
|---|---|
| Arya | arya@x.in |
| Ben | ben@x.in |
| Chloe | chloe@x.in |
5. Generated Columns
A column that a generated column is calculated from can't be dropped while the generated column exists:
ALTER TABLE students ADD COLUMN email_domain VARCHAR(40) AS (SUBSTRING_INDEX(email, '@', -1));
ALTER TABLE students DROP COLUMN email;
Query OK, 0 rows affected
Records: 0 Duplicates: 0 Warnings: 0
ERROR 3108 (HY000): Column 'email' has a generated column dependency.
6. You Can't Drop the Last Column
CREATE TABLE tiny (only_col INT);
ALTER TABLE tiny DROP COLUMN only_col;
Query OK, 0 rows affected
ERROR 1090 (42000): You can't delete all columns with ALTER TABLE; use DROP TABLE instead
Use DROP TABLE to remove the table instead.
7. Dropping Only If the Column Exists
MySQL has no DROP COLUMN IF EXISTS. Dropping a missing column is an error:
ALTER TABLE students DROP COLUMN fax;
ERROR 1091 (42000): Can't DROP 'fax'; check that column/key exists
Check information_schema.columns first in scripts, or let a migration tool (Flyway, Liquibase) record what has already run.
8. Safe Drop Checklist
- Search application code and reports for the column name.
- Check views, routines and triggers:
SELECT table_name FROM information_schema.views WHERE view_definition LIKE '%fax%'; - Check foreign keys and generated columns that use it.
- Back up the data, for example
CREATE TABLE students_fax_backup AS SELECT id, fax FROM students; - Optionally make it invisible first (
ALTER TABLE t ALTER COLUMN c SET INVISIBLE, 8.0.23+) soSELECT *stops returning it, and drop it later. - On large tables, test the time it takes; since 8.0.29 many drops are INSTANT, older versions rebuild the table.
9. Practice Exercises
Exercise 1: Drop the generated column email_domain and then the email column in one statement.
ALTER TABLE students DROP COLUMN email_domain, DROP COLUMN email;
SHOW COLUMNS FROM students;
Result: 2 rows
| Field | Type |
|---|---|
| id | int |
| name | varchar(40) |
Exercise 2: Which tables in college still have a column named title?
SELECT table_name FROM information_schema.columns
WHERE table_schema = 'college' AND column_name = 'title';
Result: 1 row
| TABLE_NAME |
|---|
| courses |
10. Summary
ALTER TABLE t DROP COLUMN c;removes the column and its data permanently.- Drop several columns in one statement with comma-separated
DROPclauses. - Drop foreign keys and dependent generated columns first; indexes and single-column CHECKs adjust automatically.
- Views are not checked and will break; recreate them.
- No IF EXISTS: check information_schema, and back up before dropping.