1
0
mirror of https://github.com/apachecn/lmpythw-zh.git synced 2025-05-28 12:02:19 +00:00
lmpythw-zh/ex40.md
wizardforcel ff54dda489 ex40
2017-08-14 17:53:03 +08:00

97 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 练习 40SQL 读取
> 原文:[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`是你的答案。