# 練習 42:SQL 刪除
> 原文:[Exercise 42: Deleting with SQL](https://learncodethehardway.org/more-python-book/ex42.html)
> 譯者:[飛龍](https://github.com/wizardforcel)
> 協議:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
> 自豪地采用[谷歌翻譯](https://translate.google.cn/)
這是最簡單的練習,但我希望你鍵入代碼之前思考一秒鐘。如果你將`SELECT`寫成`"SELECT * FROM"`,將`INSERT`寫成`"INSERT INTO"`,那么你會怎么編寫`DELETE`格式?你可以看下面,但是試著猜測它會是什么,然后看一看。
```sql
/* make sure there's dead pets */
SELECT name, age FROM pet WHERE dead = 1;
/* aww poor robot */
DELETE FROM pet WHERE dead = 1;
/* make sure the robot is gone */
SELECT * FROM pet;
/* let's resurrect the robot */
INSERT INTO pet VALUES (1, "Gigantor", "Robot", 1, 0);
/* the robot LIVES! */
SELECT * FROM pet;
```
我只是簡單地通過刪除它,然后使用`dead=0`將記錄放回去,來為機器人實現非常復雜的更新。在以后的練習中,我將向你展示,如何使用`UPDATE`來實現它,所以不要以為這是更新的真正方法。
你已經熟悉了這個腳本中的大多數行,除了第五行。這里你擁有`DELETE`,它與其他命令格式幾乎相同。你提供了`DELETE FROM table WHERE tests`,以及一種方式,將其看做移除行的`SELECT`。任何在`WHERE`子句中有效的內容在這里都有效。
## 使用其它表來刪除
記得我說過:“`DELETE`就像`SELECT`,但它從表中刪除行。” 限制是一次只能從一個表中刪除。這意味著為了刪除所有寵物,你需要執行一些額外的查詢,然后基于它們刪除。
一種方法是使用一個子查詢,根據你已經編寫的查詢來選擇要所需的 ID。還有其他的方法可以實現它,但是現在你可以根據你所知道的方法來實現它:
```sql
DELETE FROM pet WHERE id IN (
SELECT pet.id
FROM pet, person_pet, person
WHERE
person.id = person_pet.person_id AND
pet.id = person_pet.pet_id AND
person.first_name = "Zed"
);
SELECT * FROM pet;
SELECT * FROM person_pet;
DELETE FROM person_pet
WHERE pet_id NOT IN (
SELECT id FROM pet
);
SELECT * FROM person_pet;
```
第 1~8 行是正常起步的`DELETE`命令,但是`WHERE`子句使用`IN`,匹配`pet`中的`id`列與子查詢中返回的表。子查詢(也稱為子選擇)是正常的`SELECT`,在嘗試尋找人們擁有的寵物時,它應該看起來和以前你做的那個相似。
第 13~16 行中,然后我使用子查詢,將任何不存在的寵物從`person_pet`表中給刪除,使用`NOT IN`而不是`IN`。
SQL 處理它的方式是以下過程:
+ 運行末尾處括號中的子查詢,并創建一個表,帶有所有列,就像普通`SELECT`一樣。
+ 將此表視為一種臨時表,來匹配`pet.id`列。
+ 瀏覽`pet`表,并刪除擁有此臨時表中(`IN`)的 ID 的任何行。
## 挑戰練習
+ 將所有`ex2.sql`到`ex7.sql`合并到一個文件中,并重執行上述腳本,以便你只需運行一個新文件即可重新創建數據庫。
+ 添加一些東西到腳本中,來刪除其他寵物,然后再次使用新值插入它們。記住,這不是你通常更新記錄的方式,只是為了練習。
+ 練習編寫`SELECT`命令,然后將它們放在`DELETE WHERE IN`中,來刪除找到的記錄。嘗試刪除你擁有的任何死亡寵物。
+ 反著操作,刪除有死亡寵物的人。
+ 你真的需要刪除死的寵物嗎?為什么不在`person_pet`中移除他們的關系,并標記它們死了?寫一個查詢,從`person_pet`中去除死亡寵物。
## 深入學習
出于完整性,你需要閱讀[`DELETE`文檔](https://sqlite.org/lang_delete.html)。
- 笨辦法學 Python · 續 中文版
- 引言
- 第一部分:預備知識
- 練習 0:起步
- 練習 1:流程
- 練習 2:創造力
- 練習 3:質量
- 第二部分:簡單的黑魔法
- 練習 4:處理命令行參數
- 練習 5:cat
- 練習 6:find
- 練習 7:grep
- 練習 8:cut
- 練習 9:sed
- 練習 10:sort
- 練習 11:uniq
- 練習 12:復習
- 第三部分:數據結構
- 練習 13:單鏈表
- 練習 14:雙鏈表
- 練習 15:棧和隊列
- 練習 16:冒泡、快速和歸并排序
- 練習 17:字典
- 練習 18:性能測量
- 練習 19:改善性能
- 練習 20:二叉搜索樹
- 練習 21:二分搜索
- 練習 22:后綴數組
- 練習 23:三叉搜索樹
- 練習 24:URL 快速路由
- 第四部分:進階項目
- 練習 25:xargs
- 練習 26:hexdump
- 練習 27:tr
- 練習 28:sh
- 練習 29:diff和patch
- 第五部分:文本解析
- 練習 30:有限狀態機
- 練習 31:正則表達式
- 練習 32:掃描器
- 練習 33:解析器
- 練習 34:分析器
- 練習 35:解釋器
- 練習 36:簡單的計算器
- 練習 37:小型 BASIC
- 第六部分:SQL 和對象關系映射
- 練習 38:SQL 簡介
- 練習 39:SQL 創建
- 練習 40:SQL 讀取
- 練習 41:SQL 更新
- 練習 42:SQL 刪除
- 練習 43:SQL 管理
- 練習 44:使用 Python 的數據庫 API
- 練習 45:創建 ORM
- 第七部分:大作業
- 練習 46:blog
- 練習 47:bc
- 練習 48:ed
- 練習 49:sed
- 練習 50:vi
- 練習 51:lessweb
- 練習 52:moreweb