Здравствуйте! До сих пор в нашем курсе мы разбирали упражнения, которые оперировали данными только из одной таблицы. Сегодня мы это исправим и научимся делать запросы сразу к нескольким таблицам в одной базе данных.
Введение
Итак, в прошлых статьях, например по оператору SELECT в SQL, мы прописывали что то похожее:
SELECT cname FROM customers;
На самом деле изначально в языке SQL было предписано указывать поле, которое хотим выбрать в явном виде, а именно так:
SELECT customers.cname FROM customers;
Мы указываем через оператор доступа «точка» то поле, которое нужно. С течением времени, SQL стал гораздо умнее и понятнее, и на данный момент он сам понимает из какой таблице мы хотим выбрать поля, если речь идет о запросах с одной таблицей.
Если же обращаться к данным из нескольких таблиц, то хорошим тоном будет указывать явно поля, так как иногда в таблицах могут содержаться поля с одинаковыми названиями, а это потенциальная ошибка.
В SQL для многотабличных запросов продумали объединение таблиц несколькими способами, о них мы и поговорим подробнее.
Объединение таблиц в SQL
Начнем с самого простого способа, в котором будем явно указывать поля и условия, при котором их нужно выводить. Вот пример:
Вывести попарно продавцов и покупателей из одного города.
Поскольку, нужно вывести попарно то придется перебрать все комбинации — SQL сделает это:
SELECT salespeople.sname, customers.cname, customers.city FROM salespeople, customers WHERE salespeople.city = customers.city
sname | cname | city |
---|---|---|
Колованов | Деснов | Москва |
Плотников | Деснов | Москва |
Проворов | Деснов | Москва |
Колованов | Краснов | Москва |
Плотников | Краснов | Москва |
Проворов | Краснов | Москва |
Петров | Кириллов | Тверь |
Шипачев | Пушкин | Челябинск |
Мозякин | Лермонтов | Одинцово |
Колованов | Белый | Москва |
Плотников | Белый | Москва |
Проворов | Белый | Москва |
Колованов | Чудинов | Москва |
Плотников | Чудинов | Москва |
Проворов | Чудинов | Москва |
Мозякин | Лосев | Одинцово |
Это пример объединения таблиц с использованием явного определения полей. Такой запрос вполне понятен, но в будущем если будет возможность обойтись без префиксов, мы будем обходиться без них.
Объединение таблиц с помощью отношений
В SQL используются математические относительные выражения («=», «>»,»<" и т.д) для осуществления запросов. В первом примере мы использовали равенство, теперь рассмотрим другие выражения, чтобы объединить несколько таблиц. Рассмотрим пример:
Вывести пары продавец — покупатель, при условии, что у продавца комиссия ниже 20%, а у покупателя рейтинг ниже 90.
SELECT sname, comm, cname, rating FROM salespeople, customers WHERE rating < 90 and comm < 20
sname | comm | cname | rating |
---|---|---|---|
Колованов | 10 | Лермонтов | 85 |
Малкин | 18 | Лермонтов | 85 |
Колованов | 10 | Белый | 89 |
Малкин | 18 | Белый | 89 |
В наших таблицах существует 2 продавца с комиссией ниже 20% и 2 покупателя с рейтингом ниже 90 — SQL вывел все возможные комбинации.
Очевидно, что сейчас такой запрос кажется не очень полезным и применимым. Но на самом деле такие запросы могут быть использованы при фильтрации каких либо полей в веб приложении или на сайте в форме поиска. Главное, нужно понять как можно взаимодействовать сразу с несколькими таблицами в SQL.
Примеры на многотабличные запросы в SQL
1. Напишите запрос, который бы вывел список номеров Заказов, сопровождающихся именем заказчика, который создавал эти Заказы.
SELECT onum, cname FROM orders, customers WHERE orders.cnum = customers.cnum
2. Напишите запрос, который бы выдавал имена продавца и заказчика для каждого Заказа после номера Заказов.
SELECT onum, cname, sname FROM orders, customers, salespeople WHERE orders.cnum = customers.cnum and orders.snum = salespeople.snum
3. Напишите запрос, который бы выводил всех заказчиков, обслуживаемых продавцом с комиссионными выше 12%. Выведите имя заказчика, имя продавца и ставку комиссионных продавца.
SELECT cname, sname, comm FROM orders, customers, salespeople WHERE orders.cnum = customers.cnum and orders.snum = salespeople.snum and salespeople.comm > 12
4. Напишите запрос, который вычислил бы сумму комиссионных продавца для каждого Заказа заказчика с оценкой выше 90.
SELECT onum, comm FROM orders, customers, salespeople WHERE orders.cnum = customers.cnum and orders.snum = salespeople.snum and rating > 90 GROUP BY onum
5. Напишите запрос, который бы выдавал имена продавцов и заказчиков, проживающих в одном и том же городе.
SELECT sname, cname, salespeople.city FROM customers, salespeople, orders WHERE orders.cnum = customers.cnum and orders.snum = salespeople.snum and salespeople.city = customers.city
6. Напишите запрос, который бы выдавал имена продавцов и заказчиков, проживающих в одном и том же городе и суммы их приобретений.
SELECT sname, cname, salespeople.city, amt FROM customers, salespeople, orders WHERE orders.cnum = customers.cnum and orders.snum = salespeople.snum and salespeople.city = customers.city
Заключение
На этом будем заканчивать — сегодня мы познакомились с многотабличными запросами в SQL. Теперь нас ждут все более интересные и сложные запросы, но это уже в следующих темах. Если у вас остались вопросы, то оставляйте их в комментариях.
Здравствуйте, в 3м задании в запросе не нужно таблицу Orders упоминать, вся информация достается из таблицы Customers и Salespeople
Здравствуйте! Таблица orders содержит заказы, она связывает продавца и покупателя. Без нее не получится корректно определить какие заказчики связаны с продавцом(ами), у которых комиссия выше 12%
А если использовать в соединении таблиц JOIN -это усложнит процесс выборки?
Здраствуйте!