Contenido de esta guía
Respuesta rápida
Para borrar filas según datos de otra tabla puedes usar un DELETE con JOIN/USING en motores que lo soportan o un WHERE EXISTS portable. El objetivo es identificar filas de la tabla que se borra sin convertir accidentalmente la tabla auxiliar en otro objetivo de eliminación.
DELETE FROM pagos
WHERE EXISTS (
SELECT 1
FROM pedidos AS p
WHERE p.id = pagos.pedido_id
AND p.estado = 'cancelado'
);Esta forma expresa una condición de existencia y funciona bien cuando solo quieres borrar de pagos.
Haz el mismo filtro con SELECT
SELECT pa.id, pa.pedido_id, pa.importe
FROM pagos AS pa
JOIN pedidos AS p ON p.id = pa.pedido_id
WHERE p.estado = 'cancelado'
ORDER BY pa.id;Cuenta y revisa esas filas antes de ejecutar el DELETE. Si el resultado no es exactamente el esperado, corrige el JOIN o el filtro, no el DELETE.
DELETE usando otra tabla por motor
PostgreSQL: USING
DELETE FROM pagos AS pa
USING pedidos AS p
WHERE p.id = pa.pedido_id
AND p.estado = 'cancelado';USING aporta tablas para buscar coincidencias; la tabla situada tras DELETE FROM sigue siendo el objetivo.
MySQL: DELETE con JOIN
DELETE pa
FROM pagos AS pa
JOIN pedidos AS p ON p.id = pa.pedido_id
WHERE p.estado = 'cancelado';MySQL también dispone de sintaxis multitabla capaz de eliminar de más de una tabla. Si solo pretendes borrar pagos, nombra únicamente ese alias como objetivo.
SQL Server: FROM adicional
DELETE pa
FROM pagos AS pa
JOIN pedidos AS p ON p.id = pa.pedido_id
WHERE p.estado = 'cancelado';Transact-SQL admite un FROM adicional para identificar las filas que se eliminan.
SQLite: EXISTS o IN
La sintaxis documentada de SQLite para DELETE no incluye USING ni un JOIN de borrado como PostgreSQL/MySQL/SQL Server. Usa una subconsulta en WHERE, por ejemplo EXISTS.
Cascadas, triggers y transacciones
Una fila borrada puede activar claves foráneas con ON DELETE, triggers u otras reglas del motor. El preflight solo muestra las filas objetivo directas; no sustituye revisar efectos secundarios definidos en el esquema.
- Ejecuta el SELECT previo.
- Comprueba claves foráneas y cascadas.
- Usa una transacción cuando sea apropiado.
- Verifica el estado final antes de confirmar.
Copiar una sintaxis multitabla entre motores
DELETE ... USING de PostgreSQL y DELETE alias FROM ... JOIN de MySQL/SQL Server se parecen conceptualmente, pero no son intercambiables.
Práctica: elimina pagos de pedidos cancelados
Usa EXISTS para borrar solo lo necesario
La tabla pedidos contiene pedidos activos y cancelados. Elimina de pagos únicamente las filas cuyo pedido_id corresponde a un pedido cancelado.
pagos.p.id con pagos.pedido_id.p.estado = 'cancelado'.Solución razonada
DELETE FROM pagos
WHERE EXISTS (
SELECT 1
FROM pedidos AS p
WHERE p.id = pagos.pedido_id
AND p.estado = 'cancelado'
);En el fixture comprobado, se eliminan los pagos 2 y 4 y permanecen 1 y 3. La solución se ejecutó localmente con SQLite 3.46.1.
Qué debes recordar
- Previsualiza con SELECT exactamente qué filas se borrarán.
EXISTSofrece una forma clara y ampliamente portable para borrar según otra tabla.- USING/JOIN cambia de sintaxis entre PostgreSQL, MySQL y SQL Server.
- Revisa cascadas, triggers y transacciones antes de borrar.