3.3.4.9 Использование нескольких таблиц
В таблице pet
хранятся только основные данные о животных. Если же нужно
держать в базе какую-либо дополнительную информацию о них (скажем, записи
о событиях наподобие посещения ветеринара или рождения потомства),
понадобится еще одна таблица. Давайте определимся с ее структурой. Эта
таблица должна содержать:
-
имена животных, чтобы не путаться с тем, к какому животному относится
какое событие
-
дата события
-
поле для описания события
-
поле, отражающее тип события, для того, чтобы можно было распределить
их по категориям
С учетом всех приведенных выше требований можно составить примерно такую
команду CREATE TABLE
:
mysql> CREATE TABLE event (name VARCHAR(20), date DATE,
-> type VARCHAR(15), remark VARCHAR(255));
Как и в случае с таблицей 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
|
Загрузите записи с помощью следующей команды:
mysql> LOAD DATA LOCAL INFILE "event.txt" INTO TABLE event;
Используя знания, усвоенные при работе с таблицей pet
, вы сможете
загружать данные из таблицы event
; принципы здесь те же. Но что если самой
по себе таблицы event
перестанет хватать для получения нужных вам ответов?
Предположим, нужно узнать, в каком возрасте животные давали приплод. В
таблице event
указаны даты родов, но для того, чтобы рассчитать возраст
матери, нужно знать и дату ее рождения. Так как даты рождения хранятся в
таблице pet
, в этом запросе нужно использовать обе таблицы:
mysql> SELECT pet.name,
-> (TO_DAYS(date) - TO_DAYS(birth))/365 AS age,
-> remark
-> FROM pet, event
-> WHERE pet.name = event.name AND type = "litter";
+--------+------+-----------------------------+
| name | age | remark |
+--------+------+-----------------------------+
| Fluffy | 2.27 | 4 kittens, 3 female, 1 male |
| Buffy | 4.12 | 5 puppies, 2 female, 3 male |
| Buffy | 5.10 | 3 puppies, 3 female |
+--------+------+-----------------------------+
На некоторые аспекты этого запроса следует обратить особое внимание:
-
В выражении
FROM
указаны две таблицы, так как запрос будет получать
информацию из обеих.
-
При комбинировании (объединении) информации из нескольких таблиц
необходимо указать, как строки одной таблицы связываются с записями
другой. Это просто, так как в обеих таблицах есть столбец с именами. В
этом запросе выражение
WHERE
используется для сопоставления записей из
двух таблиц по значениям имен.
-
Так как столбец name присутствует в обеих таблицах, нужно явно
указать, какую именно таблицу вы имеете в виду, ссылаясь на данный
столбец. Это можно сделать, связав имя таблицы с именем столбца.
Для объединения не обязательно иметь две отдельные таблицы; иногда можно
объединить таблицу с самой собой - если нужно сравнить одни записи таблицы
с другими записями той же таблицы. Например, для того, чтобы обнаружить
среди животных ``семейные пары'', можно объединить таблицу pet
с ней
самой, составив пары животных разного пола, но одного вида:
mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
-> FROM pet AS p1, pet AS p2
-> WHERE p1.species = p2.species AND p1.sex = "f" AND p2.sex = "m";
+--------+------+--------+------+---------+
| name | sex | name | sex | species |
+--------+------+--------+------+---------+
| Fluffy | f | Claws | m | cat |
| Buffy | f | Fang | m | dog |
| Buffy | f | Bowser | m | dog |
+--------+------+--------+------+---------+
В этом запросе мы указываем псевдонимы имен таблицы, для обращения к
столбцам и определения, к какой из таблиц относится каждая ссылка на
столбец.