Оглавление

4.9. Выбор записей из нескольких таблиц

SQL-команда SELECT позволяет выбирать записи сразу из нескольких таблиц одновременно. Для этого нужно перечислить все таблицы через запятую в конструкции FROM. В конструкции WHERE через запятую указываются пары полей, являющиеся связуемыми для таблиц. Причем в условии и перечислении полей вначале указывается имя таблицы, а затем через точку имя поля.

 
Для примера выведем таблицу Customers, но вместо индекса города укажем его название:
SELECT `Customers`.`Name`, `Customers`.`Address`, `City`.`City`,
`Customers`.`Phone`

FROM `Customers`, `City`
WHERE `Customers`.`id_City`=`City`.`id_City`;

 
В итоге мы получим табл. 10.

 
Таблица 10. Данные о клиентах

 

NameAddressCityPhone
Иванов Иван ИвановичСедова, 7Санкт-Петербург125-14-46
Петров Сергей НиколаевичНевский, 88Санкт-Петербург312-12-51

 

Вместо названия таблицы можно использовать псевдоним. Псевдоним создается через ключевое слово AS после имени таблицы в конструкции FROM. Перепишем предыдущий пример с использованием псевдонимов:
SELECT `c`.`Name`, `c`.`Address`, `ct`.`City`, `c`.`Phone`
FROM `Customers` AS `c`, `City` AS `ct`
WHERE `c`.`id_City`=`ct`.`id_City`;

 
Результат будет таким же. Кроме того, если поля в таблицах имеют разные названия, то имя таблицы можно не указывать:
SELECT `Name`, `Address`, `City`, `Phone`
FROM `Customers` AS `c`, `City` AS `ct`
WHERE `c`.`id_City`=`ct`.`id_City`;

 
А теперь выведем нашу первоначальную таблицу (см. табл. 1):
SELECT `c`.`Name`, `c`.`Address`, `ct`.`City`, `c`.`Phone`, `t`.`Tovar`,
`o`.`Date_orders`, `t`.`Price`, `oi`.`Col`
FROM `Customers` AS `c`, `City` AS `ct`, `Tovar` AS `t`, `Orders` AS `o`,
`Orders_Items` AS `oi`
WHERE `c`.`id_City`=`ct`.`id_City` AND
`oi`.`id_Orders`=`o`.`id_Orders` AND
`t`.`id_Tovar`=`oi`.`id_Tovar` AND
`o`.`id_Customer`=`c`.`id_Customer`
ORDER BY `o`.`id_Orders`;

 
В итоге мы получим табл. 11.

 

NameAddressCityPhoneTovarDate_ordersPriceCol
Иванов Иван ИвановичСедова, 7Санкт-Петербург125-14-46HDD2007-06-2034001
Петров Сергей НиколаевичНевский, 88Санкт-Петербург312-12-51Тюнер2007-06-2031001
Иванов Иван ИвановичСедова, 7Санкт-Петербург125-14-46Монитор2007-06-2572001
Иванов Иван ИвановичСедова, 7Санкт-Петербург125-14-46Тюнер2007-06-3031001
Иванов Иван ИвановичСедова, 7Санкт-Петербург125-14-46CD диск
2007-07-011010
Иванов Иван ИвановичСедова, 7Санкт-Петербург125-14-46Сканер2007-07-0160001

 

 Эта таблица практически совпадает с табл. 1, с двумя исключениями:
□ нет поля Sum. Получить это поле не так уж и сложно. Достаточно перемножить значение поля Price и значение поля Col;
□ номер телефона господина Иванова изменился, так как мы его чуть раньше сами поменяли.

 
Связывать таблицы можно также с помощью оператора JOIN. Для примера выведем таблицу Customers, но вместо индекса города укажем его название:
SELECT `Customers`.`Name`, `Customers`.`Address`, `City`.`City`,
`Customers`.`Phone`
FROM `Customers` JOIN `City`
WHERE `Customers`.`id_City`=`City`.`id_City`;

 
Вместо инструкции WHERE можно использовать инструкцию ON. Например:
SELECT `Customers`.`Name`, `Customers`.`Address`, `City`.`City`,
`Customers`.`Phone`
FROM `Customers` JOIN `City`
ON `Customers`.`id_City`=`City`.`id_City`;

 
Если необходимо указать дополнительное условие выборки, то это делают в инструкции WHERE.

 

 Для примера выведем информацию о клиентах с фамилией Иванов:
SELECT `Customers`.`Name`, `Customers`.`Address`, `City`.`City`,
`Customers`.`Phone`
FROM `Customers` JOIN `City`
ON `Customers`.`id_City`=`City`.`id_City`
WHERE `Customers`.`Name` LIKE 'Иванов %';


Если названия полей в таблицах одинаковые, то вместо инструкции ON можно использовать инструкцию USING:
SELECT `Customers`.`Name`, `Customers`.`Address`, `City`.`City`,
`Customers`.`Phone`
FROM `Customers` JOIN `City` USING (`id_City`);


Оператор JOIN можно использовать также для объединения нескольких таблиц. В качестве примера выведем нашу первоначальную таблицу (см. табл. 1):
SELECT `c`.`Name`, `c`.`Address`, `ct`.`City`, `c`.`Phone`, `t`.`Tovar`,
`o`.`Date_orders`, `t`.`Price`, `oi`.`Col`
FROM `Customers` AS `c` JOIN `City` AS `ct` JOIN `Tovar` AS `t`
JOIN `Orders` AS `o` JOIN `Orders_Items` AS `oi`
ON `c`.`id_City`=`ct`.`id_City` AND
`oi`.`id_Orders`=`o`.`id_Orders` AND
`t`.`id_Tovar`=`oi`.`id_Tovar` AND
`o`.`id_Customer`=`c`.`id_Customer`
ORDER BY `o`.`id_Orders`;  (1)



Добавим нового клиента в таблицу Customers и выведем общее количество заказов каждого клиента:
INSERT INTO `Customers` VALUES
(NULL, 'Сидоров Олег Николаевич', 'Передовиков, 12', 1, '529-15-63');
SELECT `Customers`.`Name`, COUNT(`Orders`.`id_Orders`)
FROM `Customers` JOIN `Orders` USING (`id_Customer`)
GROUP BY `Orders`.`id_Customer`;

 

Получим следующий результат:
Иванов Иван Иванович 4
Петров Сергей Николаевич 1

 
Как видно из примера, этот запрос вывел только клиентов, сделавших хотя бы один заказ. Так как господин Сидоров не сделал ни одного заказа, то в таблице Orders отсутствует запись о нем. Чтобы получить всех клиентов, необходимо использовать левостороннее объединение с помощью инструкции LEFT JOIN.

 

Объединение выглядит следующим образом:
<Таблица1> LEFT [OUTER] JOIN <Таблица2> ON
<Таблица1>.<Поле1>=<Таблица2>.<Поле2>

 
Если названия полей в таблицах одинаковые, то вместо инструкции ON можно использовать инструкцию USING:
<Таблица1> LEFT [OUTER] JOIN <Таблица2> USING (<Поле>)

 
При левостороннем объединении возвращаются записи, соответствующие условию <Таблица1>.<Поле1>=<Таблица2>.<Поле2>, а также записи из таблицы <Таблица1>, которым нет соответствия в таблице <Таблица2> (при этом поля из таблицы <Таблица2> будут иметь значение NULL).

 
Выведем общее количество заказов каждого клиента с помощью левостороннего объединения:
SELECT `Customers`.`Name`, COUNT(`Orders`.`id_Orders`) AS `total`
FROM `Customers` LEFT JOIN `Orders` USING (`id_Customer`)
GROUP BY `Orders`.`id_Customer`
ORDER BY `total` DESC;

 
Получим следующий результат:
Иванов Иван Иванович 4
Петров Сергей Николаевич 1
Сидоров Олег Николаевич 0

 
Кроме левостороннего объединения можно использовать правостороннее объединение с помощью инструкции RIGHT JOIN. Объединение выглядит следующим образом:
<Таблица1> RIGHT [OUTER] JOIN <Таблица2> ON
<Таблица1>.<Поле1>=<Таблица2>.<Поле2>

 
Если названия полей в таблицах одинаковые, то вместо инструкции ON можно использовать инструкцию USING:
<Таблица1> RIGHT [OUTER] JOIN <Таблица2> USING (<Поле>)

 

При правостороннем объединении возвращаются записи, соответствующие условию <Таблица1>.<Поле1>=<Таблица2>.<Поле2>, а также записи из таблицы <Таблица2>, которым нет соответствия в таблице <Таблица1> (при этом поля из таблицы <Таблица1> будут иметь значение NULL).

 
Выведем общее количество заказов каждого клиента с помощью правостороннего объединения:
SELECT `Customers`.`Name`, COUNT(`Orders`.`id_Orders`) AS `total`
FROM `Orders` RIGHT JOIN `Customers` USING (`id_Customer`)
GROUP BY `Orders`.`id_Customer`
ORDER BY `total` DESC;

 
В этом примере мы просто поменяли местами таблицы в инструкции FROM:
FROM `Orders` RIGHT JOIN `Customers`

 

 

Примечания:
  • Оператор JOIN имеет два синонима: CROSS JOIN и INNER JOIN.
Комментарии принадлежат их авторам. Мы не несем ответственности за их содержание.
Отправитель Нити