SQL
Tutorial SQL: Eliminación de datos: DELETE
Aprende a usar la sentencia DELETE en SQL para eliminar datos con condiciones precisas y conoce diferencias clave con TRUNCATE.
Aprende SQL y certifícateSintaxis DELETE FROM
La sentencia DELETE es una de las operaciones fundamentales en SQL que permite eliminar registros de una tabla. Esta operación forma parte del lenguaje de manipulación de datos (DML) junto con INSERT y UPDATE, que ya hemos estudiado en lecciones anteriores.
La sintaxis básica del comando DELETE es sencilla pero potente, permitiéndonos eliminar desde un único registro hasta todos los registros de una tabla. Veamos su estructura:
DELETE FROM nombre_tabla
WHERE condición;
Los componentes principales de esta sentencia son:
- DELETE FROM: Indica la operación de eliminación y la tabla objetivo.
- WHERE: Cláusula opcional que especifica qué registros deben eliminarse.
Si omitimos la cláusula WHERE, la sentencia eliminará todos los registros de la tabla, manteniendo la estructura de la misma. Por ello, es crucial tener precaución al ejecutar sentencias DELETE.
Ejemplos básicos
Veamos algunos ejemplos prácticos para entender mejor cómo funciona:
Ejemplo 1: Eliminar un registro específico por su identificador único:
DELETE FROM clientes
WHERE id = 25;
Este comando elimina el cliente cuyo ID es 25.
Ejemplo 2: Eliminar múltiples registros que cumplan una condición:
DELETE FROM productos
WHERE precio < 10;
Esta sentencia elimina todos los productos con precio menor a 10.
Ejemplo 3: Eliminar todos los registros de una tabla:
DELETE FROM registros_temporales;
Al omitir la cláusula WHERE, se eliminan todos los registros de la tabla "registros_temporales".
Uso de operadores en la cláusula WHERE
Podemos utilizar diversos operadores en la cláusula WHERE para definir condiciones más específicas:
- Operadores de comparación (=, <>, <, >, <=, >=):
DELETE FROM pedidos
WHERE fecha_entrega < '2023-01-01';
- Operadores lógicos (AND, OR, NOT):
DELETE FROM empleados
WHERE departamento = 'Ventas' AND fecha_contratacion < '2020-01-01';
- Operador LIKE para patrones de texto:
DELETE FROM mensajes
WHERE asunto LIKE '%spam%';
- Operador IN para múltiples valores posibles:
DELETE FROM productos
WHERE categoria_id IN (3, 7, 9);
- Operador BETWEEN para rangos:
DELETE FROM transacciones
WHERE fecha BETWEEN '2023-01-01' AND '2023-01-31';
DELETE con subconsultas
También podemos utilizar subconsultas en la cláusula WHERE para crear condiciones más complejas:
DELETE FROM productos
WHERE proveedor_id IN (
SELECT id
FROM proveedores
WHERE pais = 'Italia'
);
Este ejemplo elimina todos los productos cuyos proveedores son de Italia.
Consideraciones importantes
Al trabajar con DELETE, es importante tener en cuenta:
Irreversibilidad: Una vez ejecutado, DELETE no se puede deshacer fácilmente sin una copia de seguridad.
Restricciones de integridad referencial: Si existen claves foráneas que hacen referencia a los registros que intentamos eliminar, la operación puede fallar a menos que se hayan configurado acciones en cascada.
Rendimiento: Las operaciones DELETE que afectan a muchos registros pueden ser costosas en términos de rendimiento, especialmente en tablas grandes.
Buenas prácticas:
- Siempre hacer una copia de seguridad antes de ejecutar DELETE en datos importantes.
- Probar primero con un SELECT para verificar qué registros serán afectados.
- Considerar el uso de transacciones para operaciones complejas.
-- Verificar primero qué registros se eliminarán
SELECT * FROM clientes WHERE ultima_compra < '2020-01-01';
-- Si el resultado es correcto, proceder con el DELETE
DELETE FROM clientes WHERE ultima_compra < '2020-01-01';
Diferencias entre MySQL y PostgreSQL
Aunque la sintaxis básica de DELETE es similar en MySQL y PostgreSQL, existen algunas diferencias sutiles:
- MySQL permite una sintaxis alternativa para eliminar registros de múltiples tablas en una sola sentencia:
DELETE t1, t2
FROM tabla1 t1
JOIN tabla2 t2 ON t1.id = t2.tabla1_id
WHERE t1.fecha < '2023-01-01';
- PostgreSQL utiliza una sintaxis diferente para eliminar con joins:
DELETE FROM tabla1
USING tabla2
WHERE tabla1.id = tabla2.tabla1_id AND tabla2.activo = false;
La comprensión adecuada de la sintaxis DELETE FROM es esencial para mantener la integridad y calidad de los datos en nuestras bases de datos, permitiéndonos eliminar información obsoleta o incorrecta de manera controlada y precisa.
Condiciones de eliminación
Las condiciones de eliminación en SQL son el mecanismo principal para determinar qué registros serán eliminados al ejecutar una sentencia DELETE. Estas condiciones, especificadas en la cláusula WHERE, actúan como un filtro que permite realizar eliminaciones selectivas y precisas en lugar de borrar todos los datos de una tabla.
Importancia de las condiciones bien definidas
Definir condiciones de eliminación adecuadas es crucial por varias razones:
- Previenen la eliminación accidental de datos importantes
- Permiten operaciones de limpieza específicas y controladas
- Mejoran el rendimiento al limitar el alcance de la operación
- Mantienen la integridad de los datos relacionados
Tipos de condiciones para DELETE
Podemos clasificar las condiciones de eliminación según su complejidad y propósito:
Condiciones simples
Las condiciones simples utilizan un solo criterio para filtrar los registros:
DELETE FROM usuarios
WHERE estado = 'inactivo';
DELETE FROM productos
WHERE fecha_caducidad < CURRENT_DATE;
Condiciones compuestas
Combinan múltiples criterios mediante operadores lógicos (AND, OR, NOT):
DELETE FROM pedidos
WHERE (estado = 'cancelado' AND fecha < '2023-01-01')
OR (estado = 'pendiente' AND fecha < '2022-06-01');
Este tipo de condiciones permite crear filtros más precisos para situaciones complejas.
Condiciones basadas en relaciones
Utilizan la relación entre tablas para determinar qué registros eliminar:
DELETE FROM detalles_pedido
WHERE pedido_id IN (
SELECT id FROM pedidos
WHERE cliente_id = 1045 AND estado = 'cancelado'
);
Estrategias para condiciones de eliminación seguras
Verificación previa con SELECT
Una práctica recomendada es verificar primero qué registros serán afectados utilizando la misma condición en una consulta SELECT:
-- Primero verificamos
SELECT * FROM clientes
WHERE ultima_visita < '2022-01-01' AND tipo = 'prueba';
-- Si el resultado es correcto, procedemos con la eliminación
DELETE FROM clientes
WHERE ultima_visita < '2022-01-01' AND tipo = 'prueba';
Uso de LIMIT en MySQL
MySQL permite limitar el número de filas afectadas por una operación DELETE, lo que puede ser útil para operaciones graduales en tablas grandes:
DELETE FROM logs_sistema
WHERE fecha < '2023-01-01'
ORDER BY fecha
LIMIT 1000;
Esta técnica es especialmente útil cuando necesitamos eliminar grandes volúmenes de datos sin bloquear la tabla por períodos prolongados.
Eliminación por lotes en PostgreSQL
PostgreSQL no soporta LIMIT en DELETE directamente, pero podemos lograr un efecto similar usando subconsultas:
DELETE FROM logs_sistema
WHERE id IN (
SELECT id FROM logs_sistema
WHERE fecha < '2023-01-01'
ORDER BY fecha
LIMIT 1000
);
Condiciones con funciones
Las funciones pueden enriquecer nuestras condiciones de eliminación, permitiendo operaciones más sofisticadas:
Funciones de fecha
-- Eliminar registros de hace más de un año
DELETE FROM estadisticas_temporales
WHERE fecha < DATE_SUB(CURRENT_DATE, INTERVAL 1 YEAR); -- MySQL
-- Equivalente en PostgreSQL
DELETE FROM estadisticas_temporales
WHERE fecha < CURRENT_DATE - INTERVAL '1 year';
Funciones de texto
-- Eliminar usuarios con dominios de correo específicos
DELETE FROM usuarios
WHERE LOWER(email) LIKE '%@dominio-temporal.com';
Funciones matemáticas y agregadas
-- Eliminar productos con bajo rendimiento de ventas
DELETE FROM productos
WHERE id IN (
SELECT producto_id
FROM ventas
GROUP BY producto_id
HAVING SUM(cantidad) < 10
);
Condiciones para casos especiales
Eliminación basada en duplicados
Para eliminar registros duplicados, manteniendo solo una instancia:
-- En MySQL
DELETE t1 FROM contactos t1
INNER JOIN contactos t2
WHERE t1.id > t2.id AND t1.email = t2.email;
-- En PostgreSQL
DELETE FROM contactos
WHERE id IN (
SELECT id FROM (
SELECT id,
ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) as rn
FROM contactos
) t
WHERE t.rn > 1
);
Eliminación condicional con CASE
Podemos usar expresiones CASE para crear condiciones más dinámicas:
DELETE FROM inventario
WHERE
CASE
WHEN categoria = 'perecedero' THEN fecha_caducidad < CURRENT_DATE
WHEN categoria = 'electrónico' THEN fecha_ultima_venta < DATE_SUB(CURRENT_DATE, INTERVAL 2 YEAR)
ELSE false
END;
Consideraciones de rendimiento
Las condiciones de eliminación también afectan el rendimiento de la operación:
- Índices: Las condiciones basadas en columnas indexadas se ejecutan más rápidamente
- Complejidad: Las condiciones muy complejas pueden ralentizar la ejecución
- Volumen: Eliminar grandes cantidades de datos puede afectar el rendimiento general
-- Más eficiente (si id está indexado)
DELETE FROM logs WHERE id < 1000;
-- Menos eficiente (si texto no está indexado)
DELETE FROM logs WHERE mensaje LIKE '%error%';
Condiciones de eliminación y transacciones
Para operaciones de eliminación críticas, es recomendable utilizar transacciones que permitan revertir los cambios en caso de error:
-- En MySQL y PostgreSQL
BEGIN;
DELETE FROM facturas WHERE cliente_id = 500;
DELETE FROM clientes WHERE id = 500;
COMMIT;
Si ocurre algún problema entre las dos operaciones DELETE, podemos usar ROLLBACK para deshacer los cambios y mantener la integridad de los datos.
Las condiciones de eliminación bien diseñadas son fundamentales para mantener la calidad e integridad de los datos, permitiendo operaciones de limpieza precisas y controladas que eliminan solo la información que realmente debe ser removida de nuestras bases de datos.
DELETE vs TRUNCATE
Cuando necesitamos eliminar datos de una tabla en SQL, disponemos de dos comandos principales: DELETE y TRUNCATE. Aunque ambos tienen el mismo objetivo final —eliminar registros—, funcionan de manera fundamentalmente diferente y cada uno resulta más adecuado en situaciones específicas.
Diferencias principales
La elección entre DELETE y TRUNCATE depende de varios factores clave:
Alcance de la eliminación: DELETE puede eliminar registros específicos mediante condiciones, mientras que TRUNCATE siempre elimina todos los registros.
Velocidad de ejecución: TRUNCATE es significativamente más rápido, especialmente en tablas grandes.
Registro de operaciones: DELETE registra cada fila eliminada en el log de transacciones, TRUNCATE solo registra la liberación de las páginas de datos.
Comportamiento con restricciones: DELETE respeta las restricciones de integridad referencial, TRUNCATE requiere que no existan referencias a la tabla.
Sintaxis comparativa
La sintaxis de ambos comandos refleja sus diferentes enfoques:
-- Sintaxis DELETE
DELETE FROM nombre_tabla
WHERE condición;
-- Sintaxis TRUNCATE
TRUNCATE TABLE nombre_tabla;
Observa que TRUNCATE no admite una cláusula WHERE, lo que refuerza su naturaleza de "todo o nada".
Funcionamiento interno
Para entender mejor las diferencias, es importante conocer cómo funciona cada comando internamente:
DELETE
- Elimina los registros uno por uno
- Mantiene un registro detallado en el log de transacciones
- Conserva el espacio asignado a la tabla
- Mantiene los valores de las secuencias o identity
-- Eliminar clientes inactivos
DELETE FROM clientes WHERE ultima_actividad < '2022-01-01';
-- Eliminar todos los registros (pero menos eficiente que TRUNCATE)
DELETE FROM registros_temporales;
TRUNCATE
- Elimina las páginas de datos completas en lugar de filas individuales
- Reinicia los contadores de identidad (AUTO_INCREMENT en MySQL, SERIAL en PostgreSQL)
- Libera el espacio de almacenamiento (excepto el reservado por la definición de la tabla)
- Requiere permisos más elevados en algunos sistemas
-- Vaciar completamente una tabla de logs
TRUNCATE TABLE logs_sistema;
-- En PostgreSQL se puede omitir la palabra TABLE
TRUNCATE logs_sistema;
Impacto en el rendimiento
La diferencia de rendimiento entre ambos comandos puede ser dramática:
En una tabla con millones de registros, un DELETE sin condición podría tardar minutos, mientras que TRUNCATE completaría la operación en segundos.
El impacto en el log de transacciones también es significativo:
-- Puede generar gigabytes de logs en tablas grandes
DELETE FROM tabla_grande;
-- Genera una entrada mínima en el log
TRUNCATE TABLE tabla_grande;
Comportamiento con transacciones
El comportamiento transaccional varía entre ambos comandos:
- DELETE es completamente transaccional:
BEGIN;
DELETE FROM pedidos WHERE cliente_id = 100;
-- Si algo falla, podemos hacer ROLLBACK
COMMIT;
- TRUNCATE tiene comportamiento variable según el sistema:
- En PostgreSQL es transaccional y se puede revertir
- En MySQL (InnoDB) también es transaccional desde versiones recientes
- En SQL Server implica un commit implícito de la transacción actual
-- En PostgreSQL
BEGIN;
TRUNCATE TABLE tabla_temporal;
-- Si algo falla, podemos hacer ROLLBACK
COMMIT;
Restricciones y limitaciones
Existen situaciones donde no podemos usar TRUNCATE:
- Cuando hay referencias de clave foránea: TRUNCATE fallará si existen restricciones de integridad referencial activas que apunten a la tabla.
-- Esto fallará si hay claves foráneas que referencian a clientes
TRUNCATE TABLE clientes;
-- Alternativa usando DELETE
DELETE FROM clientes;
Cuando necesitamos condiciones: Si necesitamos eliminar solo ciertos registros, TRUNCATE no es una opción.
Cuando hay triggers: En muchos sistemas, los triggers de DELETE no se activan con TRUNCATE.
Casos de uso recomendados
Usar DELETE cuando:
- Necesitamos eliminar registros específicos basados en condiciones
- Requerimos mantener la integridad referencial automáticamente
- Necesitamos que se ejecuten triggers asociados a la eliminación
- Queremos mantener los valores de secuencias o identity
- Necesitamos registrar detalladamente cada eliminación
-- Eliminar productos descontinuados
DELETE FROM productos WHERE estado = 'descontinuado';
-- Limpieza de datos específicos
DELETE FROM logs WHERE nivel = 'debug' AND fecha < CURRENT_DATE - INTERVAL '30 days';
Usar TRUNCATE cuando:
- Necesitamos eliminar todos los registros de una tabla
- Buscamos el máximo rendimiento en la operación
- Queremos reiniciar contadores de identidad
- La tabla es temporal o de staging sin referencias externas
- Estamos en una fase de desarrollo o pruebas
-- Vaciar tablas temporales al final del proceso
TRUNCATE TABLE tmp_resultados_proceso;
TRUNCATE TABLE tmp_estadisticas;
-- Reiniciar una tabla para cargar datos desde cero
TRUNCATE TABLE productos_importacion;
Diferencias específicas en MySQL y PostgreSQL
Aunque la funcionalidad básica es similar, existen algunas diferencias entre sistemas:
MySQL
- Permite TRUNCATE en tablas con particiones
- Soporta la sintaxis
TRUNCATE nombre_tabla
(sin la palabra TABLE) - Con InnoDB, TRUNCATE es transaccional en versiones recientes
-- Sintaxis válida en MySQL
TRUNCATE logs_sistema;
PostgreSQL
- Permite truncar múltiples tablas en una sola sentencia
- Ofrece opciones adicionales como CASCADE y RESTART IDENTITY
- Es completamente transaccional
-- Truncar múltiples tablas relacionadas en PostgreSQL
TRUNCATE TABLE tabla1, tabla2, tabla3 CASCADE;
-- Reiniciar secuencias explícitamente
TRUNCATE TABLE productos RESTART IDENTITY;
Verificación previa a la eliminación
Independientemente del método elegido, es recomendable verificar los datos antes de eliminarlos:
-- Antes de DELETE, verificar qué se eliminará
SELECT COUNT(*) FROM logs WHERE fecha < '2023-01-01';
-- Antes de TRUNCATE, verificar el contenido de la tabla
SELECT COUNT(*) FROM tabla_temporal;
La elección entre DELETE y TRUNCATE debe basarse en los requisitos específicos de cada situación, considerando factores como el volumen de datos, la necesidad de condiciones, las restricciones de integridad y el rendimiento requerido. Ambos comandos son herramientas valiosas que, utilizadas correctamente, nos permiten mantener nuestras bases de datos optimizadas y libres de información innecesaria.
Otras lecciones de SQL
Accede a todas las lecciones de SQL y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Sql
Introducción Y Entorno
Ddl Y Dml
Introducción Y Entorno
Instalación De Mysql
Introducción Y Entorno
Instalación De Postgresql
Introducción Y Entorno
Tipos De Datos
Introducción Y Entorno
Bases De Datos Y Tablas
Introducción Y Entorno
Sistemas De Gestión De Bases De Datos
Introducción Y Entorno
Tipos De Bases De Datos
Introducción Y Entorno
Creación De Bases De Datos Y Tablas: Create Database, Create Table
Sintaxis Dml Crud
Consultas Básicas De Selección: Select Y Where
Sintaxis Dml Crud
Inserción De Datos: Insert Into
Sintaxis Dml Crud
Actualización De Datos: Update
Sintaxis Dml Crud
Eliminación De Datos: Delete
Sintaxis Dml Crud
Introducción A Dml
Sintaxis Dml Crud
Consultar Datos: Select
Sintaxis Dml Crud
Clasificación De Resultados Con Order By
Filtros Y Clasificación
Filtrado De Valores Únicos Con Distinct
Filtros Y Clasificación
Paginación Con Limit Y Offset
Filtros Y Clasificación
Alterar La Estructura De Tablas Existentes: Alter Table
Sintaxis Ddl
Renombrar Tablas Y Bases De Datos: Rename
Sintaxis Ddl
Vaciar Tablas Y Bases De Datos: Drop
Sintaxis Ddl
Uso De Funciones Agregadas: Count, Sum, Avg, Max, Min
Funciones Y Agrupación
Agrupación De Resultados Con Group By
Funciones Y Agrupación
Filtrado De Grupos De Resultados Con Having
Funciones Y Agrupación
Funciones Numéricas Y Matemáticas
Funciones Y Agrupación
Funciones De Fecha Y Hora
Funciones Y Agrupación
Funciones De Texto
Funciones Y Agrupación
Many To One
Asociaciones Entre Tablas
One To Many
Asociaciones Entre Tablas
One To One
Asociaciones Entre Tablas
Many To Many
Asociaciones Entre Tablas
Relaciones Entre Tablas
Joins Y Subqueries
Uso De Inner Join, Left Join, Right Join, Full Join
Joins Y Subqueries
Creación Y Uso De Subqueries
Joins Y Subqueries
Left Join Y Right Join
Joins Y Subqueries
Full Join
Joins Y Subqueries
Cross Join Y Self Join
Joins Y Subqueries
Optimización De Consultas
Sintaxis Avanzada
Uso De Índices Y Particiones
Sintaxis Avanzada
Uso De Vistas
Sintaxis Avanzada
Triggers Y Eventos
Sintaxis Avanzada
Particiones
Sintaxis Avanzada
Restricciones E Integridad
Sintaxis Avanzada
Transacciones
Sintaxis Avanzada
Vistas Materializadas
Sintaxis Avanzada
Rollback
Sintaxis Avanzada
Vistas Con Create View
Sintaxis Avanzada
Principios Acid
Sintaxis Avanzada
Manejo De Errores Y Excepciones
Sintaxis Avanzada
Funciones Ventana
Sintaxis Avanzada
Índices
Sintaxis Avanzada
Expresiones De Tabla Comunes (Cte) Con With
Sintaxis Avanzada
Creación Y Uso De Funciones
Programación En Sql
Creación Y Uso De Procedimientos Almacenados
Programación En Sql
Variables Y Control De Flujo
Programación En Sql
Creación Y Manejo De Usuarios Y Roles
Seguridad Y Administración
Asignación Y Gestión De Permisos
Seguridad Y Administración
Copias De Seguridad Y Restauración De Bases De Datos
Seguridad Y Administración
Ejercicios de programación de SQL
Evalúa tus conocimientos de esta lección Eliminación de datos: DELETE con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Tipos de datos
Inserción de datos: INSERT INTO
Filtrado de grupos de resultados con HAVING
Uso de índices y particiones
Renombrar tablas y bases de datos: RENAME
Uso de vistas
Uso de INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN
Agrupación de resultados con GROUP BY
Creación y uso de subqueries
Sentencias INSERT
Copias de seguridad y restauración de bases de datos
Uso de INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN
Instalación de MySQL
Relaciones entre tablas
Eliminación de datos: DELETE
Creación de bases de datos y tablas: CREATE DATABASE, CREATE TABLE
Creación y uso de funciones
Creación de tablas e inserción de datos con SQL
Uso de funciones agregadas: COUNT, SUM, AVG, MAX, MIN
Optimización de consultas
Introducción a SQL
Triggers y eventos
Clasificación de resultados con ORDER BY
Alterar la estructura de tablas existentes: ALTER TABLE
Eliminación de datos: DELETE
Instalación de PostgreSQL
Creación y uso de procedimientos almacenados
Consultas básicas de selección: SELECT y WHERE
Vaciar tablas y bases de datos: DROP
Actualización de datos: UPDATE
Creación y manejo de usuarios y roles
Consultas básicas de selección SELECT y WHERE
Creación de bases de datos y tablas
Bases de datos y tablas
Actualización de datos: UPDATE
Relaciones entre tablas
Filtrado de valores únicos con DISTINCT
Asignación y gestión de permisos
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender la sintaxis básica y avanzada del comando DELETE en SQL.
- Aprender a definir condiciones de eliminación precisas y seguras usando operadores y subconsultas.
- Diferenciar entre DELETE y TRUNCATE, entendiendo sus usos, ventajas y limitaciones.
- Aplicar buenas prácticas para evitar pérdidas accidentales de datos y optimizar el rendimiento.
- Conocer diferencias específicas en la implementación de DELETE y TRUNCATE en MySQL y PostgreSQL.