Sql Scholl
Распечатать страницу
Перейти на главную Карта сайта Отправить сообщение

Подзапросы

Использование подзапросов в качестве вычисляемых полей

       Другой способ использования подзапросов состоит в использовании вычисляемых полей. Предположим, вы хотите вывести общее количество заказов, размещенных каждым клиентом в таблице Customers (клиенты). Заказы хранятся в таблице Orders вместе с соответствующими идентификаторами клиентов.

      Чтобы выполнить эту операцию, необходимо сделать следующее.

     1.    Выбрать перечень клиентов из таблицы Customers.

     2.    Для каждого выбранного клиента посчитать число егозаказов в таблице Orders.

     Как следует из предыдущих двух уроков, вы можете использовать оператор SELECT COUNT (*) для подсчета строк в таблице, а используя предложение WHERE для фильтрации идентификатора конкретного клиента, вы можете подсчитать заказы только этого клиента. Например, посредством следующего кода можно подсчитать количество заказов, сделанных клиентом 1000000001:

SELECT COUNT(*) AS orders
FROM Orders
WHERE cust_id = '1000000001';

     Чтобы получить итоговую информацию посредством функции COUNT (*) для каждого клиента, используйте COUNT* как подзапрос. Посмотрите на следующий код:

SELECT cust_name, cust_state,(SELECT COUNT(*)
FROM Orders
WHERE Orders.cust_id = Customers.cust_id) AS orders FROM Customers ORDER BY cust_name; 



cust name         cust_state        orders 
------------      ---------------   -------------------
Fun4All           IN                1
Fun4All           AZ                1
Kids Place        OH                0
The Toy Store     IL                1
Village Toys      MI                2

      Этот оператор SELECT возвращает три столбца для каждого клиента из таблицы Customers: cust_name, cust_state и orders. Поле Orders является вычисляемым; оно формируется в результате выполнения подзапроса, который заключен в круглые скобки. Этот подзапрос выполняется один раз для каждого выбранного клиента. В приведенном примере подзапрос выполняется пять раз, потому что были выбраны имена пяти клиентов.

      Предложение WHERE в подзапросе несколько отличается от предложений WHERE, с которыми мы работали ранее, потому что в нем используются полные имена столбцов. Следующее предложение требует от SQL, чтобы было проведено сравнение значения cust_id в таблице Orders с тем, которое в данный момент выбирается из таблицы Customers: WHERE Orders.cust_id = Customers.cust_id

      Этот синтаксис — имя таблицы и имя столбца разделяются точкой — должен использоваться всякий раз, когда может возникнуть неопределенность в именах столбцов. В данном примере имеется два столбца cust_id, один в таблице Customers и один в таблице Orders. Без использования полностью определенных имен столбцов СУБД будет считать, что вы сравниваете cust_id в таблице Orders с самим собой. Поэтому запрос  SELECT COUNT(*)   FROM Orders WHERE cust_id = cust_id будет всегда возвращать общее число заказов в таблице Orders, но это не тот результат, который вам нужен:

SELECT cust_name, cust_state, (SELECT COUNT(*)
FROM Orders
WHERE cust_id = cust_id) AS orders FROM Customers ORDER BY cust_name; 



cust_name      cust state      orders 
------------   ------------    ----------------
Fun4All        IN              5
Fun4All        AZ              5
Kids Place     OH              5
The Toy Store  IL              5
Village Toys   MI              5

     Подзапросы чрезвычайно полезны при подготовке оператора SELECT такого типа, однако внимательно следите за тем, чтобы были правильно указаны неоднозначные имена столбцов.

Всегда есть несколько решений

Хотя простой код, представленный в этом уроке, и работоспособен, зачастую он оказывается не самым эффективным способом выборки данных такого типа. Мы еще раз рассмотрим этот пример в одном из следующих уроков.