ALTER TABLE DROP COLUMN
La cláusula DROP COLUMN de ALTER TABLE elimina una columna de una tabla existente. La columna y todos sus datos se borran permanentemente. Es una operación irreversible, así que conviene verificar que la columna ya no se necesita antes de ejecutarla.
Sintaxis
ALTER TABLE nombre_tabla
DROP COLUMN nombre_columna;La palabra COLUMN es opcional: DROP nombre_columna funciona igual.
Tabla de ejemplo
CREATE TABLE empleados_demo (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(100) NOT NULL,
email VARCHAR(150) NOT NULL,
telefono VARCHAR(20),
direccion VARCHAR(255),
codigo_interno CHAR(8),
notas TEXT,
salario DECIMAL(10, 2) NOT NULL,
fecha_alta DATE NOT NULL
);
INSERT INTO empleados_demo (nombre, email, telefono, direccion, codigo_interno, notas, salario, fecha_alta) VALUES
('Ana García', 'ana@empresa.com', '612345678', 'Calle Mayor 15', 'EMP-0001', 'Departamento de ventas', 35000.00, '2023-01-15'),
('Luis Martín', 'luis@empresa.com', '623456789', 'Av. Diagonal 220', 'EMP-0002', NULL, 42000.00, '2022-06-01'),
('Eva López', 'eva@empresa.com', NULL, NULL, 'EMP-0003', 'Recién incorporada', 38000.00, '2024-03-10');Eliminar una columna
ALTER TABLE empleados_demo
DROP COLUMN notas;Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
La columna notas y todos sus valores desaparecen. Para verificar:
DESCRIBE empleados_demo;| Field | Type | Null | Key | Default | Extra |
|---|---|---|---|---|---|
| id | int | NO | PRI | NULL | auto_increment |
| nombre | varchar(100) | NO | NULL | ||
| varchar(150) | NO | NULL | |||
| telefono | varchar(20) | YES | NULL | ||
| direccion | varchar(255) | YES | NULL | ||
| codigo_interno | char(8) | YES | NULL | ||
| salario | decimal(10,2) | NO | NULL | ||
| fecha_alta | date | NO | NULL |
Eliminar múltiples columnas
Puedes eliminar varias columnas en una sola sentencia:
ALTER TABLE empleados_demo
DROP COLUMN telefono,
DROP COLUMN direccion,
DROP COLUMN codigo_interno;Query OK, 0 rows affected (0.04 sec)
Combinar varias eliminaciones es más eficiente que ejecutar sentencias separadas, ya que MySQL solo reconstruye la tabla una vez.
SELECT * FROM empleados_demo;| id | nombre | salario | fecha_alta | |
|---|---|---|---|---|
| 1 | Ana García | ana@empresa.com | 35000.00 | 2023-01-15 |
| 2 | Luis Martín | luis@empresa.com | 42000.00 | 2022-06-01 |
| 3 | Eva López | eva@empresa.com | 38000.00 | 2024-03-10 |
No puedes eliminar todas las columnas
Una tabla debe tener al menos una columna. Si intentas eliminar la última:
CREATE TABLE una_columna (
valor INT
);
ALTER TABLE una_columna DROP COLUMN valor;ERROR 1090 (42000): You can't delete all columns with ALTER TABLE; use DROP TABLE instead
Si necesitas eliminar la tabla completa, usa DROP TABLE.
Columnas con índices
Si la columna que quieres eliminar tiene un índice, MySQL elimina el índice automáticamente:
ALTER TABLE empleados_demo
ADD COLUMN departamento VARCHAR(50),
ADD INDEX idx_departamento (departamento);
-- El índice se elimina junto con la columna
ALTER TABLE empleados_demo
DROP COLUMN departamento;MySQL se encarga de la limpieza del índice. No necesitas eliminarlo manualmente antes.
Columnas con clave foránea
Si la columna es parte de una clave foránea, debes eliminar la clave foránea antes de eliminar la columna:
CREATE TABLE departamentos_demo (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(50) NOT NULL
);
ALTER TABLE empleados_demo
ADD COLUMN departamento_id INT,
ADD CONSTRAINT fk_dept
FOREIGN KEY (departamento_id) REFERENCES departamentos_demo(id);Intentar eliminar directamente:
ALTER TABLE empleados_demo
DROP COLUMN departamento_id;ERROR 1828 (HY000): Cannot drop column 'departamento_id': needed in a foreign key constraint 'fk_dept'
Primero elimina la clave foránea, después la columna:
ALTER TABLE empleados_demo
DROP FOREIGN KEY fk_dept,
DROP COLUMN departamento_id;Ambas operaciones se pueden combinar en una sola sentencia.
Columnas referenciadas por otras tablas
Si una columna es referenciada por la clave foránea de otra tabla, tampoco puedes eliminarla directamente:
CREATE TABLE proyectos_demo (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(100),
responsable_id INT,
FOREIGN KEY (responsable_id) REFERENCES empleados_demo(id)
);No podrías eliminar la columna id de empleados_demo porque proyectos_demo depende de ella. Tendrías que eliminar o modificar la clave foránea en proyectos_demo primero.
Columnas con CHECK
Si la columna tiene una restricción CHECK, MySQL la elimina automáticamente:
ALTER TABLE empleados_demo
ADD COLUMN edad INT CHECK (edad >= 18);
-- La restricción CHECK se elimina con la columna
ALTER TABLE empleados_demo
DROP COLUMN edad;Columnas generadas que dependen de otra
Si una columna generada depende de la columna que quieres eliminar, MySQL devuelve un error:
ALTER TABLE empleados_demo
ADD COLUMN salario_mensual DECIMAL(10, 2)
GENERATED ALWAYS AS (salario / 12) STORED;
ALTER TABLE empleados_demo
DROP COLUMN salario;ERROR 3108 (HY000): Column 'salario' has a generated column dependency.
Debes eliminar primero la columna generada:
ALTER TABLE empleados_demo
DROP COLUMN salario_mensual,
DROP COLUMN salario;Combinar DROP con otras operaciones
Puedes mezclar eliminaciones con otras modificaciones:
ALTER TABLE empleados_demo
ADD COLUMN puesto VARCHAR(100) NOT NULL DEFAULT 'General',
ADD COLUMN activo BOOLEAN DEFAULT TRUE;DESCRIBE empleados_demo;| Field | Type | Null | Key | Default | Extra |
|---|---|---|---|---|---|
| id | int | NO | PRI | NULL | auto_increment |
| nombre | varchar(100) | NO | NULL | ||
| varchar(150) | NO | NULL | |||
| salario | decimal(10,2) | NO | NULL | ||
| fecha_alta | date | NO | NULL | ||
| puesto | varchar(100) | NO | General | ||
| activo | tinyint(1) | YES | 1 |
Precauciones
Antes de eliminar una columna, verifica que no hay código de aplicación (consultas, vistas, procedimientos almacenados, triggers) que la referencie. MySQL no comprueba estas dependencias automáticamente: la eliminación tiene éxito, pero las consultas que usen esa columna fallarán después.
Para verificar si una columna se usa en vistas:
SELECT TABLE_NAME, VIEW_DEFINITION
FROM information_schema.VIEWS
WHERE TABLE_SCHEMA = DATABASE()
AND VIEW_DEFINITION LIKE '%nombre_columna%';Para verificar en procedimientos almacenados:
SELECT ROUTINE_NAME, ROUTINE_TYPE
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = DATABASE()
AND ROUTINE_DEFINITION LIKE '%nombre_columna%';Limpieza
DROP TABLE IF EXISTS proyectos_demo;
DROP TABLE IF EXISTS empleados_demo;
DROP TABLE IF EXISTS departamentos_demo;
DROP TABLE IF EXISTS una_columna;En el siguiente artículo veremos cómo renombrar tablas con RENAME TABLE.
Escrito por Eduardo Lázaro
