Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
lmpythw-zh
提交
cd7e4a82
L
lmpythw-zh
项目概览
OpenDocCN
/
lmpythw-zh
大约 1 年 前同步成功
通知
0
Star
18
Fork
5
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
lmpythw-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cd7e4a82
编写于
8月 15, 2017
作者:
W
wizardforcel
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ex42
上级
e7a50104
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
81 addition
and
0 deletion
+81
-0
ex42.md
ex42.md
+81
-0
未找到文件。
ex42.md
0 → 100644
浏览文件 @
cd7e4a82
# 练习 42:SQL 删除
> 原文:[EExercise 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
)
。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录