PHP скрипты

MySQL

Apache

phpMyADmin

2.16: Использование нескольких таблиц в одном SQL запросе

Главная Страница » Книги по PHP » MySQL уроки для начинающих с нуля » Использование нескольких таблиц в одном SQL запросе

Таблица pet описывает, какие домашние животные у вас есть. Если вы хотите записывать другую информацию о них, вроде событий в их жизни: посещений ветеринара или когда рождения потомства, вы нуждаетесь в другой таблице. Что эта таблица должна включать? Требуется:

  • имя, чтобы вы знали, к которому животному каждое событие относится;
  • дата, чтобы вы знали, когда событие произошло;
  • поле, чтобы описать событие;
  • поле типа события, если вы хотите разложить события по категориям.

Согласно этим данным, инструкция CREATE TABLE для таблицы событий (event) могла бы выглядеть следующим образом:

mysql> CREATE TABLE event (name VARCHAR(20), date DATE,
   -> type VARCHAR(15), remark VARCHAR(255));

Как с таблицей pet, проще всего загрузить начальные записи, создав разграниченный табуляциями текстовый файл, содержащий информацию. Дополнительные данные о зверинце показаны в табл. 2.3:

Таблица 2.3. Дополнительные данные о зверинце.

Fluffy 1995-05-15 Потомство 4 котенка, 3 female, 1 male
Buffy 1993-06-23 Потомство 5 щенков, 2 female, 3 male
Buffy 1994-06-19 Потомство 3 щенка, 3 female
Chirpy 1999-03-21 Ветеринар Необходимо выпрямление клюва
Slim 1997-08-03 Ветеринар Сломано ребро
Bowser 1991-10-12 Конура  
Fang 1991-10-12 Конура  
Fang
Claws
1998-08-28
1998-03-17
День рождения
День рождения
Подарок: новая жевательная игрушка
Подарок: ошейник от блох
Whistler 1998-12-09 День рождения Первый день рождения

Загрузите записи так:

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 указывает сразу две таблицы потому, что запрос должен получить информацию из обеих таблиц;
  • при объединении (joining) информации из многих таблиц, вы должны определить, как записи в одной таблице могут быть согласованы с записями в другой. Это просто потому, что они обе имеют столбец nаmе. Запрос использует предложение WHERE, чтобы заставить совпасть записи в двух таблицах, основываясь на значениях паmе;
  • поскольку столбец nаmе есть в обеих таблицах, вы должны указать, относительно какой таблицы вы его обозначаете. Это выполняется путем добавления имени таблицы к имени столбца;
  • наконец отметим новую функцию TO_DAYS(), которая переводит дату в виде год-месяц-день в число дней.

Вы не обязательно должны иметь две различные таблицы, чтобы выполнить объединение. Иногда полезно присоединить таблицу к самой себе, если вы хотите сравнивать записи в таблице с другими записями в той же самой таблице. Например, чтобы найти размножающиеся пары среди ваших домашних животных, вы можете соединять таблицу pet с самой собой, чтобы объединить самцов и самок одной разновидности.

Но вот проблема: сравнивать таблицу саму с собой по правилам языка SQL нельзя! Однако если очень хочется, то можно обойти ограничение языка. Для этого таблице можно присвоить сразу два псевдонима с помощью уже упомянутого ранее ключевого слова AS и сравнить таблицы под псевдонимами. Тут ограничение не работает: таблицы-то называются по-разному! Например:

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   | кошка   |
| Buffy  | f   | Fang   | m   | собака  |
| Buffy  | f   | Bowser | m   | собака  |
+--------|-----|--------|-----|---------|

В этом запросе мы определяем псевдонимы для имени таблицы, чтобы обратиться к столбцам и указываем прямо, с которым образцом таблицы каждая ссылка столбца связана.

Поделиться с друзьями