# 练习 40:SQL 读取
> 原文:[Exercise 40: Reading with SQL](https://learncodethehardway.org/more-python-book/ex40.html)
> 译者:[飞龙](https://github.com/wizardforcel)
> 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
> 自豪地采用[谷歌翻译](https://translate.google.cn/)
在 CRUD 矩阵中,你只知道“创建”。你可以创建表,你可以在这些表中创建行。现在我将告诉你如何“读取”,或者在 SQL 中是`SELECT`:
```sql
SELECT * FROM person;
SELECT name, age FROM pet;
SELECT name, age FROM pet WHERE dead = 0;
SELECT * FROM person WHERE first_name != "Zed";
```
这里是每一行做的事情:
`ex5.sql:1`
这表示“从`person`中选择所有列并返回所有行”。`SELECT`的格式是`SELECT what FROM tables(s) WHERE (tests)`,`WHERE`子句是可选的。`*`(星号)字符是你想要的所有列。
`ex5.sql:3`
这里我只要从`pet`表请求两列,`name`和`age`。它将返回所有行。
`ex5.sql:5`
现在我正在从`pet`寻找相同的列,但是我只请求`dead = 0`的行。这会给我所有的活着的宠物。
`ex5.sql:7`
最后,我从`person`选择所有列,就像在第一行,但我现在指明,它们不等于`"Zed"`。`WHERE`子句决定哪一行返回,哪一行不返回。
## 选择多表
希望你现在专注于选择数据。永远记住这一点:SQL 只知道表。SQL 喜欢表。SQL 仅返回表。表,表,表,表! 我以这种非常疯狂的方式重复一遍,以便你将开始意识到,你在编程中知道的东西不会有帮助。你在编程中处理图,在 SQL 中处理表。他们是相关的概念,但心智模型是不同的。
这里是一个例子,它们哪里不一样。假设你想知道 Zed 拥有什么宠物。你需要写一个`SELECT`,在`person`中查找,然后“以某种方式”找到我的宠物。为此,你必须查询`person_pet`表来获取所需的`id`列。以下是我的做事方式:
```sql
SELECT pet.id, pet.name, pet.age, pet.dead
FROM pet, person_pet, person
WHERE
pet.id = person_pet.pet_id AND
person_pet.person_id = person.id AND
person.first_name = "Zed";
```
现在它看起来很庞大,但我会把它拆解,所以你可以看到,他只是简单构造新的表,基于三个表中的数据,和`WHERE`子句。
`ex6.sql:1`
我仅仅想要`pet`中的一些列,所以我在选择中指定它们。在上一个练习中,你使用`*`来表示“每一列”,但它在这里是一个坏主意。相反,你想要明确地指定你想要的每个表中的哪个列,你可以使用`table.column`实现它,就像`pet.name`。
`ex6.sql:2`
为了将`pet`连接到`person`,我需要遍历`person_pet`关系表。在 SQL 中,这意味着我需要在`FROM`之后列出所有三个表。
`ex6.sql:3`
`WHERE`子句的开始。
`ex6.sql:4`
首先,我将`pet`连接到`person_pet`,通过相关 ID 列`pet.id`和`person_pet.id`。
`ex6.sql:5`
并且我需要以相同的方式,将人`person`连接到`person_pet`。现在,数据库可以仅仅搜索 id 列全部匹配的行,这些就是连接的行。
`ex6.sql:6`
我最后仅仅请求自己拥有的宠物,通过为我的名称添加`person.first_name`测试。
## 挑战练习
+ 写一个查询,查找所有超过 10 年的宠物。
+ 写一个查询,查找所有比你年轻的人。然后查找比你年长的人。
+ 编写一个查询,`WHERE`子句中使用多于一个测试,使用`AND`来编写它。例如`WHERE first_name = "Zed" AND age > 30`。
+ 执行另一个查询,使用三个条件,并使用`AND`和`OR`运算符来搜索行。
+ 如果你已经知道像 Python 或 Ruby 这样的语言,这可能是一个查看数据的令人惊奇的方式。花时间使用类和对象来构建相同的关系,然后将其映射到此配置。
+ 执行一个查询,查找你到目前为止添加的宠物。
+ 更改查询来使用你的`person.id`而不是`person.name`,像我一样。
+ 浏览运行的输出,并确保你知道哪些 SQL 命令生成了哪个表,以及如何生成该输出。
## 深入学习
通过阅读[`SELECT`命令的文档](https://sqlite.org/lang_select.html),继续深入了解 SQLite3,同时阅读[`EXPLAIN QUERY PLAN`功能的文档](https://sqlite.org/eqp.html)。如果你不知道为什么 SQLite3 做了一些事情,`EXPLAIN`是你的答案。
- 笨办法学 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