The pet
table keeps track of which pets you have. pet
表记录您养的宠物。If you want to record other information about them, such as events in their lives like visits to the vet or when litters are born, you need another table. What should this table look like? 如果你想记录关于他们的其他信息,比如他们生活中的一些事件,比如去看兽医或者一窝婴儿出生时,你需要另一张桌子。这张桌子应该是什么样子?It needs to contain the following information:它需要包含以下信息:
The pet name so that you know which animal each event pertains to.宠物的名字,这样你就可以知道每件事都与哪种动物有关。
A date so that you know when the event occurred.一个日期,以便您知道事件发生的时间。
A field to describe the event.描述事件的字段。
An event type field, if you want to be able to categorize events.事件类型字段,如果希望能够对事件进行分类。
Given these considerations, the 考虑到这些因素,CREATE TABLE
statement for the event
table might look like this:event
表的CREATE TABLE
语句可能如下所示:
mysql>CREATE TABLE event (name VARCHAR(20), date DATE,
type VARCHAR(15), remark VARCHAR(255));
As with the 与pet
table, it is easiest to load the initial records by creating a tab-delimited text file containing the following information.pet
表一样,通过创建包含以下信息的以制表符分隔的文本文件来加载初始记录是最容易的。
name | date | type | remark |
---|---|---|---|
Fluffy | 1995-05-15 | litter | 4 kittens, 3 female, 1 male |
Buffy | 1993-06-23 | litter | 5 puppies, 2 female, 3 male |
Buffy | 1994-06-19 | litter | 3 puppies, 3 female |
Chirpy | 1999-03-21 | vet | needed beak straightened |
Slim | 1997-08-03 | vet | broken rib |
Bowser | 1991-10-12 | kennel | |
Fang | 1991-10-12 | kennel | |
Fang | 1998-08-28 | birthday | Gave him a new chew toy |
Claws | 1998-03-17 | birthday | Gave him a new flea collar |
Whistler | 1998-12-09 | birthday | First birthday |
Load the records like this:按如下方式加载记录:
mysql> LOAD DATA LOCAL INFILE 'event.txt' INTO TABLE event;
Based on what you have learned from the queries that you have run on the 根据您从pet
table, you should be able to perform retrievals on the records in the event
table; the principles are the same. pet
表上运行的查询中学到的知识,您应该能够对event
表中的记录执行检索;原则是一样的。But when is the 但什么时候event
table by itself insufficient to answer questions you might ask?event
表本身不足以回答您可能提出的问题?
Suppose that you want to find out the ages at which each pet had its litters. 假设你想知道每只宠物产仔的年龄。We saw earlier how to calculate ages from two dates. 我们在前面看到了如何从两个日期计算年龄。The litter date of the mother is in the 母亲的产仔日期在event
table, but to calculate her age on that date you need her birth date, which is stored in the pet
table. event
表中,但要计算她在该日期的年龄,您需要她的出生日期,该日期存储在pet
表中。This means the query requires both tables:这意味着查询需要两个表:
mysql>SELECT pet.name,
TIMESTAMPDIFF(YEAR,birth,date) AS age,
remark
FROM pet INNER JOIN event
ON pet.name = event.name
WHERE event.type = 'litter';
+--------+------+-----------------------------+ | name | age | remark | +--------+------+-----------------------------+ | Fluffy | 2 | 4 kittens, 3 female, 1 male | | Buffy | 4 | 5 puppies, 2 female, 3 male | | Buffy | 5 | 3 puppies, 3 female | +--------+------+-----------------------------+
There are several things to note about this query:关于此查询,有几点需要注意:
The FROM
clause joins two tables because the query needs to pull information from both of them.FROM
子句连接两个表,因为查询需要从这两个表中提取信息。
When combining (joining) information from multiple tables, you need to specify how records in one table can be matched to records in the other. 组合(连接)多个表中的信息时,需要指定如何将一个表中的记录与另一个表中的记录进行匹配。This is easy because they both have a 这很容易,因为它们都有一个name
column. name
列。The query uses an 查询使用ON
clause to match up records in the two tables based on the name
values.ON
子句根据name
值匹配两个表中的记录。
The query uses an 查询使用INNER JOIN
to combine the tables. INNER JOIN
来组合表。An 当且仅当两个表都满足INNER JOIN
permits rows from either table to appear in the result if and only if both tables meet the conditions specified in the ON
clause. ON
子句中指定的条件时,INNER JOIN
才允许两个表中的行出现在结果中。In this example, the 在本例中,ON
clause specifies that the name
column in the pet
table must match the name
column in the event
table. ON
子句指定pet
表中的name
列必须与event
表中的name
列匹配。If a name appears in one table but not the other, the row does not appear in the result because the condition in the 如果一个名称出现在一个表中而不是另一个表中,则该行不会出现在结果中,因为ON
clause fails.ON
子句中的条件失败。
Because the 因为name
column occurs in both tables, you must be specific about which table you mean when referring to the column. name
列出现在两个表中,所以在引用该列时,必须具体说明所指的表。This is done by prepending the table name to the column name.这是通过在列名前加上表名来完成的。
You need not have two different tables to perform a join. 执行联接不需要两个不同的表。Sometimes it is useful to join a table to itself, if you want to compare records in a table to other records in that same table. 有时,如果要将表中的记录与同一表中的其他记录进行比较,将表连接到表本身是很有用的。For example, to find breeding pairs among your pets, you can join the 例如,要在您的宠物中找到繁殖配对,您可以将宠物表自身加入,以生成同类的活雄、雌配对:pet
table with itself to produce candidate pairs of live males and females of like species:
mysql>SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
FROM pet AS p1 INNER JOIN pet AS p2
ON p1.species = p2.species
AND p1.sex = 'f' AND p1.death IS NULL
AND p2.sex = 'm' AND p2.death IS NULL;
+--------+------+-------+------+---------+ | name | sex | name | sex | species | +--------+------+-------+------+---------+ | Fluffy | f | Claws | m | cat | | Buffy | f | Fang | m | dog | +--------+------+-------+------+---------+
In this query, we specify aliases for the table name to refer to the columns and keep straight which instance of the table each column reference is associated with.在这个查询中,我们为表名指定别名以引用列,并明确每个列引用与表的哪个实例关联。