该pet
表跟踪您拥有哪些宠物。如果您想记录关于他们的其他信息,例如他们生活中的事件,例如看兽医或小窝出生的时间,您需要另一张表。这张桌子应该是什么样子的?它需要包含以下信息:
宠物名称,以便您知道每个事件属于哪种动物。
一个日期,以便您知道事件发生的时间。
描述事件的字段。
事件类型字段,如果您希望能够对事件进行分类。
考虑到这些因素,该表的CREATE
TABLE
语句event
可能如下所示:
mysql> CREATE TABLE event (name VARCHAR(20), date DATE,
type VARCHAR(15), remark VARCHAR(255));
与pet
表格一样,通过创建一个包含以下信息的制表符分隔的文本文件来加载初始记录是最简单的。
姓名 | 日期 | 类型 | 评论 |
---|---|---|---|
蓬松的 | 1995-05-15 | 垃圾 | 4只小猫,3只雌性,1只雄性 |
巴菲 | 1993-06-23 | 垃圾 | 5只小狗,2只雌性,3只雄性 |
巴菲 | 1994-06-19 | 垃圾 | 3只小狗,3只母狗 |
扢 | 1999-03-21 | 兽医 | 需要拉直喙 |
瘦 | 1997-08-03 | 兽医 | 肋骨断了 |
鲍泽 | 1991-10-12 | 狗窝 | |
芳 | 1991-10-12 | 狗窝 | |
芳 | 1998-08-28 | 生日 | 给了他一个新的咀嚼玩具 |
爪子 | 1998-03-17 | 生日 | 给他一个新的跳蚤项圈 |
惠斯勒 | 1998-12-09 | 生日 | 周岁生日 |
像这样加载记录:
mysql> LOAD DATA LOCAL INFILE 'event.txt' INTO TABLE event;
根据您从对pet
表运行的查询中学到的知识,您应该能够对
event
表中的记录执行检索;原则是一样的。但是什么时候event
表格本身不足以回答您可能会问的问题?
假设您想要找出每只宠物产仔的年龄。我们之前看到了如何根据两个日期计算年龄。母亲的出生日期在
event
表中,但要计算她在该日期的年龄,您需要她的出生日期,该日期存储在
pet
表中。这意味着查询需要两个表:
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 |
+--------+------+-----------------------------+
这个查询有几点需要注意:
该
FROM
子句连接两个表,因为查询需要从它们中提取信息。当组合(连接)来自多个表的信息时,您需要指定一个表中的记录如何与另一个表中的记录相匹配。这很容易,因为它们都有一
name
列。该查询使用ON
子句根据name
值匹配两个表中的记录。查询使用
INNER JOIN
来组合表。当且仅当两个表都满足子句中指定的INNER JOIN
条件时,才会允许任一表中的行出现在结果中 。ON
在此示例中,该ON
子句指定 表中的name
列pet
必须与表中的name
列 匹配event
。如果一个名称出现在一个表中但没有出现在另一个表中,则该行不会出现在结果中,因为ON
子句中的条件不成立。因为该
name
列出现在两个表中,所以您在引用该列时必须具体说明您指的是哪个表。这是通过将表名添加到列名来完成的。
您不需要有两个不同的表来执行连接。如果要将表中的记录与同一表中的其他记录进行比较,有时将表与其自身连接很有用。例如,要在您的宠物中找到繁殖对,您可以将pet
表与自身连接起来,以生成同类物种的活雄性和雌性候选对:
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 |
+--------+------+-------+------+---------+
在此查询中,我们为表名指定别名以引用列,并明确每个列引用与表的哪个实例相关联。