Ir al contenido
wannacode

DELETE: borrar filas

En resumen: DELETE FROM … WHERE borra las filas que cumplen la condición; sin WHERE desaparecen todas, y una clave foránea prohíbe borrar una fila a la que apuntan otras.

Problema

Quita mi reseña

En enero Maria escribió una reseña del detergente en polvo: «El paquete llegó roto.» La tienda le envió un paquete nuevo. Ahora Maria escribe a soporte y pide que se quite la reseña.

La fila tiene que desaparecer de reviews. Solo esa, no las otras reseñas de Maria.

La idea

DELETE FROM … WHERE

DELETE FROM dice de qué tabla, y WHERE dice qué filas:

SQLbase de datos: tienda

La reseña 7 ya no está, y la otra reseña de Maria, la del pan blanco, sigue ahí. DELETE quita filas enteras. No se listan columnas.

La fila se borra solo en esta base de datos. «Base nueva» la devuelve.

Pruébalo

Una cuenta cerrada

Teodora Genova (cliente 19) se registró en septiembre pero no ha pedido nada. Hoy cierra su cuenta. Bórrala.

SQLbase de datos: tienda

Míralo

Un cliente con pedidos

Maria también quiere cerrar su cuenta. Pruébalo:

SQLbase de datos: tienda

La base de datos se niega. Maria tiene 12 pedidos y dos reseñas, y apuntan a ella con una clave foránea (customer_id). Si su fila desapareciera, los pedidos no pertenecerían a nadie.

Es una regla de la tabla, como UNIQUE y CHECK de la primera lección. En el módulo siguiente la escribirás tú y elegirás qué pasa con los pedidos cuando se borra al cliente.

Míralo

DELETE sin WHERE

Olvida WHERE y desaparece cada fila:

SQLbase de datos: tienda

16 reseñas, reunidas a lo largo de un año entero, desaparecen con una sola sentencia. La tabla se queda, pero vacía. Haz clic en «Base nueva» para recuperarlas.

Con los clientes no funciona así:

SQLbase de datos: tienda

La mayoría de los clientes tiene pedidos, así que toda la sentencia se anula. Ni siquiera se borran los clientes sin pedidos: o se ejecuta toda la sentencia, o no se ejecuta nada. Así que la costumbre de la lección anterior vale también aquí: primero un SELECT con el mismo WHERE.

La idea

Borrado lógico (soft delete)

Georgi Petrov cancela su pedido nuevo 57. Borrarlo no funciona, porque el pedido tiene productos:

SQLbase de datos: tienda

Podrías borrar primero sus filas de order_items y después el pedido en sí. Pero las tiendas rara vez lo hacen. En su lugar el pedido se cancela:

SQLbase de datos: tienda

Esto es un borrado lógico (soft delete): la fila se queda, pero marcada como borrada o cancelada. Por qué lo prefieren las tiendas:

  • Los informes siguen siendo correctos. Cuántos pedidos se cancelan, y por qué, es una pregunta importante.
  • La contabilidad necesita cada pedido que tuvo un pago.
  • Soporte ve el historial cuando llama el cliente.
  • Un error se puede arreglar. Lo cancelado vuelve con un UPDATE. Lo borrado no vuelve.

El precio es que cada consulta tiene que acordarse de los cancelados. El informe de ventas necesita WHERE status <> 'cancelled'.

Más precisamente, para curiosos

En muchos sistemas cada tabla tiene una columna deleted_at: NULL para las filas vivas, una fecha para las «borradas». Entonces cada consulta lleva WHERE deleted_at IS NULL. Cómo añadir una columna a una tabla lo verás en el módulo siguiente.

A veces borrar es obligatorio. Cuando una persona pide que se eliminen sus datos (el «derecho al olvido» del RGPD), los datos personales tienen que irse. A menudo se borran o se sustituyen el nombre y el correo, y los pedidos se quedan sin ellos para las cuentas.

Pruébalo

Sin pepinos

Los pepinos (producto 13) se han agotado. La tienda los quita del pedido nuevo 57, y los demás productos del pedido se quedan.

SQLbase de datos: tienda

Ejercicio

Dos tareas

1. Boris Mitev (boris.mitev@example.com) quiere que se quiten sus reseñas. Bórralas, encontrando al cliente por el correo con una subconsulta.

Sin las reseñas de Boris:

SQLbase de datos: tienda

2. La banitsa de queso y los pepinos se han agotado y no volverán antes de fin de mes. Quita los productos agotados (stock 0) de los pedidos nuevos (status = 'new'). Los pedidos antiguos son historial y no se tocan.

Los pedidos nuevos sin los productos agotados:

SQLbase de datos: tienda

Test

Ponte a prueba

1. ¿Por qué DELETE FROM customers WHERE id = 1; da un error?
2. ¿Qué hace DELETE FROM reviews; sin WHERE?
3. ¿Por qué la tienda cancela un pedido (status = cancelled) en lugar de borrarlo?
4. ¿Qué borra DELETE FROM order_items WHERE product_id = 13;?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·