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;
FieldTypeNullKeyDefaultExtra
idintNOPRINULLauto_increment
nombrevarchar(100)NONULL
emailvarchar(150)NONULL
telefonovarchar(20)YESNULL
direccionvarchar(255)YESNULL
codigo_internochar(8)YESNULL
salariodecimal(10,2)NONULL
fecha_altadateNONULL

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;
idnombreemailsalariofecha_alta
1Ana Garcíaana@empresa.com35000.002023-01-15
2Luis Martínluis@empresa.com42000.002022-06-01
3Eva Lópezeva@empresa.com38000.002024-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;
FieldTypeNullKeyDefaultExtra
idintNOPRINULLauto_increment
nombrevarchar(100)NONULL
emailvarchar(150)NONULL
salariodecimal(10,2)NONULL
fecha_altadateNONULL
puestovarchar(100)NOGeneral
activotinyint(1)YES1

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