Към съдържанието
wannacode

DELETE: изтриване на редове

Накратко: DELETE FROM изтрива редовете, които WHERE избере, а без WHERE изпразва цялата таблица.

Проблем

Махни отзива ми

През януари Мария писа отзив за праха за пране: „Пакетът пристигна скъсан.“ Магазинът ѝ прати нов пакет. Сега Мария пише в поддръжката и моли отзивът да се махне.

Редът трябва да изчезне от reviews. Само той, без другите отзиви на Мария.

Идеята

DELETE FROM … WHERE

DELETE FROM казва от коя таблица, а WHERE казва кои редове:

SQLбаза: магазин

Отзив 7 го няма, а другият отзив на Мария, за белия хляб, си стои. DELETE маха цели редове. Колони не се изброяват.

Редът е изтрит само в тази база. „Нова база“ го връща.

Пробвай

Закрит профил

Теодора Генова (клиент 19) се регистрира през септември, но не е поръчала нищо. Днес закрива профила си. Изтрий я.

SQLбаза: магазин

Виж го

Клиент с поръчки

Мария също иска да закрие профила си. Опитай:

SQLбаза: магазин

Базата отказва. Мария има 12 поръчки и два отзива, а те сочат към нея с външен ключ (customer_id). Ако редът ѝ изчезне, поръчките ще са на никого.

Това е правило на таблицата, както UNIQUE и CHECK от първия урок. В следващия модул ще го пишеш сам и ще избираш какво да става с поръчките, когато клиентът се изтрие.

Виж го

DELETE без WHERE

Забравиш ли WHERE, изчезват всички редове:

SQLбаза: магазин

16 отзива, събирани цяла година, изчезват с една заявка. Таблицата остава, но е празна. Натисни „Нова база“, за да ги върнеш.

С клиентите не става така:

SQLбаза: магазин

Повечето клиенти имат поръчки, затова цялата заявка се отказва. Не се трият и клиентите без поръчки: или се изпълнява цялата заявка, или нищо. Затова и тук важи навикът от предишния урок: първо SELECT със същото WHERE.

Идеята

Меко изтриване

Георги Петров се отказва от новата си поръчка 57. Изтриването не става, защото в поръчката има продукти:

SQLбаза: магазин

Можеш първо да изтриеш редовете ѝ от order_items, а после самата поръчка. Но магазините рядко го правят. Вместо това поръчката се отказва:

SQLбаза: магазин

Това е меко изтриване: редът остава, но е отбелязан като изтрит или отказан. Защо магазините го предпочитат:

  • Отчетите остават верни. Колко поръчки се отказват и защо е важен въпрос.
  • Счетоводството има нужда от всяка поръчка, по която е имало плащане.
  • Поддръжката вижда историята, когато клиентът се обади.
  • Грешката се поправя. Отказаното се връща с един UPDATE. Изтритото не се връща.

Цената е, че всяка заявка трябва да помни за отказаните. Отчетът за продажбите трябва да има WHERE status <> 'cancelled'.

По-точно, за любопитните

В много системи всяка таблица има колона deleted_at: NULL за живите редове, дата за „изтритите“. Тогава всяка заявка има WHERE deleted_at IS NULL. Как се добавя колона към таблица ще видиш в следващия модул.

Понякога изтриването е задължително. Когато човек поиска данните му да се махнат (правото „да бъдеш забравен“ в GDPR), личните данни трябва да изчезнат. Често името и имейлът се изтриват или заменят, а поръчките остават без тях за счетоводството.

Пробвай

Без краставици

Краставиците (продукт 13) свършиха. Магазинът ги маха от новата поръчка 57, а другите продукти в нея остават.

SQLбаза: магазин

Упражнение

Две задачи

1. Борис Митев (boris.mitev@example.com) иска отзивите му да се махнат. Изтрий ги, като намериш клиента по имейла с подзаявка.

Без отзивите на Борис:

SQLбаза: магазин

2. Баницата и краставиците свършиха и няма да има до края на месеца. Махни изчерпаните продукти (наличност 0) от новите поръчки (status = 'new'). Старите поръчки са история и не се пипат.

Без изчерпаните продукти в новите поръчки:

SQLбаза: магазин

Тест

Провери се

1. Защо DELETE FROM customers WHERE id = 1; дава грешка?
2. Какво прави DELETE FROM reviews; без WHERE?
3. Защо магазинът отказва поръчка (status = cancelled), вместо да я изтрие?
4. Какво трие DELETE FROM order_items WHERE product_id = 13;?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·