FROM shop a, clients b
WHERE (a.Tovar = b.Tovar) AND
Price = (SELECT MAX(Price) FROM shop)
Информация о товарах хранится в таблице БД shop.db,a сведения о покупателях - в таблице client.db.С помощью подзапроса из таблицы shop. dbвыбирается запись, содержащая максимальное значение в поле Price(Цена товара). Затем в таб лице client.db отбираются все записи, для которых значение поля Tovar совпадает с названием выбранного с помощью подзапроса товара, и из этих записей выделяется требуемая информация о покупателях.
Весьма распространенной ошибкой начинающих программистов является использование вложенного запроса, который может вместо единичного значения возвращать список значений:
SELECT *
FROM flat
WHERE Number = (SELECT Number
FROM flat
WHERE Room = 3)
В данном случае результатом вложенного запроса является множество значений. Попытка сравнить единичное значение поля с таким множеством приведет к инициированию исключительной ситуации. Поэтому подобное использование подзапросов недопустимо. Правильным решением в данном случае может быть указание в условии поиска вместо знака равенства оператора IN, обеспечивающего возможность выбора одного из нескольких значений:
SELECT *
FROM flat
WHERE Number IN (SELECT Number
FROM flat
WHERE Room = 3)
Любой подзапрос может также иметь вложенный запрос, который, в свою очередь, может содержать подзапрос, и т.д. Данная возможность достаточно широко используется на практике.
Предположим, что имеется таблица dom. bd, содержащая список всех жильцов дома. Следующий запрос позволяет вывести список жителей квартиры, в которой живет самый старый жилец дома.
SELECT a.* FROM dom a WHERE a.Nom_kv IN
(SELECT b.Nom_kv FROM dom b WHERE b.Vozrast =
(SELECT MAX(c.Vozrast) FROM dom c))
Поясним логику формирования данного запроса. Вначале, в подзапросе с самой большой глубиной вложения, выбирается максимальное значение в поле Vozrast (Возраст жильца). Затем в подзапросе, расположенном на уровень выше предыдущего, определяется номер квартиры (поле Nom_kv), где проживает жилец, возраст которого равен отобранному максимальному значению. И, наконец, основной запрос отбирает все записи, относящиеся к жильцам данной квартиры, то есть записи, у которых значение поля Nom_kv совпадает с отобранным значением. Если существует несколько старейших жильцов, у которых возраст одинаков, то также будет выведен список проживающих с ними в одних квартирах.
Следует обратить внимание на использование псевдонимов в данном запросе. Как видно из текста запроса, одна и та же таблица используется и в основном, и во вложенном запросе. В подоб-. ной ситуации обязательно применяются псевдонимы, поскольку в противном случае при сравнении полей будет неясно, когда происходит обращение к полю, относящемуся к основному запросу, а когда - к вложенному. Использование имен таблиц в данном случае также не поможет, так как данные берутся из одной и той же таблицы, а поэтому во избежание ошибки следует указать соответствующие псевдонимы.
Бывают случаи, когда возникает необходимость отбирать записи, для которых вложенный запрос возвращает одно или несколько значений, но при этом решающим является факт существования некоторого значения, а не само это значение (например, имеет значение только сам факт покупки, независимо от того, что именно было куплено, на какую сумму и т.п.). В таком случае может быть использован оператор EXISTS.
SELECT DISTINCT a.Name, a.Address
FROM clients a
WHERE EXISTS (SELECT b.Customer
FROM shop b
WHERE a.Name = b.Customer)
Вышеприведенный запрос позволяет получить список имен и адресов всех покупателей, которые сделали хотя бы одну покупку в данной фирме.
При использовании подзапросов, возвращающих множество значений, могут применяться специальные операторы ALL, SOME или ANY.
Оператор ALL указывает на то, что условие поиска будет истинным, если сравниваемое значение находится в определенном отношении со всеми значениями, возвращаемыми подзапросом. Поясним сказанное на небольшом примере.
Допустим, имеется таблица liga. db, в которой хранится информация обо всех игроках футбольной лиги. Запрос, представленный ниже, позволяет вывести сведения об игроках, возраст которых меньше любого из значений среднего возраста игроков, определяемого для каждой команды в отдельности.
SELECT *
FROM liga a
WHERE a.Vozrast < ALL
(SELECT AVG(b.Vozrast) FROM liga b GROUP BY b.Komanda)
Действия операторов SOME и ANY абсолютно одинаковы. Они показывают, что условие истинно, когда сравниваемое значение находится в нужном отношении хотя бы с одним значением, возвращаемым подзапросом.
Если немного изменить предьщущий запрос, подставив операнд ANY вместо операнда ALL, то запрос принимает следующий вид:
SELECT *
FROM liga a
WHERE a.Vozrast < ANY
(SELECT AVG(b.Vozrast) FROM liga b GROUP BY b.Komanda)
Результатом выполнения такого запроса будет список всех игроков, у которых возраст меньше хотя бы одного из средних значений возрастов, определяемых по каждой отдельной команде.
Рассмотрим простейшую ситуацию, когда в таблице содержатся данные об игроках только двух команд, и средний возраст игроков первой команды - 23 года, а второй команды - 25 лет. В случае использования первого из приведенных запросов (с операндом ALL) в результирующий список попадут только игроки, имеющие возраст меньше 23 лет (меньше любого из средних значений - как первого, так и второго). В случае же применения второго запроса (с операндом ANY) в результирующем списке окажутся все игроки, имеющие возраст менее 25 лет (меньше хотя бы одного из средних значений).
Объединение запросов.
В некоторых случаях требуется объединить результаты выполнения нескольких операторов SELECT. Такое объединение производится с помощью оператора UNION. При этом результирующие наборы данных должны иметь одинаковый формат, то есть одинаковый состав возвращаемых полей и полное совпадение типов данных соответствующих полей. Если в результирующих наборах данных, сформированных после выполнения различных запросов, имеется одна и та же запись, то она не дублируется в сводном наборе данных.'
Ниже показано, как можно объединить результаты выполнения трех запросов. В рассматриваемом примере осуществляется отбор данных из таблицы anim. db, содержащей информацию о различных животных. Таблица включает такие поля: название животного (Animal), длина тела животного (Dlina), вес животного (Ves).
Первый запрос выводит записи, у которых поле Animal имеет значение «Бурозубка». Второй запрос выбирает из таблицы записи, для которых значение поля Dlina равно 12. Третий запрос отбирает записи, значение поля Ves которых превосходит 300.
SELECT *
FROM anim
WHERE Animal = ЛБурозубка'
UNION
SELECT *
FROM anim
WHERE Dlina = 12 UNION SELECT * FROM anim WHERE Ves > 300
На рис. 15.4 представлен пример выполнения вышеприведенного объединения запросов.
В рассмотренном примере объединяются данные, отбираемые с помощью различных запросов из одной и той же таблицы. В общем случае это не обязательно, т.е. могут быть объединены и данные из различных таблиц. Однако в таком случае нужно более внимательно следить за совпадением типов данных полей и порядком их вывода в объединяемых за просах.
Контрольні питання
1. Розглянути роботу оператора Select
2. Описати роботу формату команди Select
САМОСТІЙНА РОБОТА СТУДЕНТА
ЗМІСТОВИЙ МОДУЛЬ 6: ПРОГРАМУВАННЯ З ГРАФАМИ
ТЕМА 6.7: НАВІГАЦІЯ ПО НАБОРУ ДАНИХ. МОВА SQL. СТВОРЕННЯ ДОВІДКОВОЇ СИСТЕМИ
Самостійне заняття №45 –Модифікація набору даних
План заняття
1. Характеристика роботи оператора Update
2. Огляд формату написання оператора Update
SQL позволяет осуществлять редактирование записей путем изменения значений полей в группе записей. Для этого используется оператор UPDATE,который описывается следующим образом:
UPDATE Имя_таблицы
SET Имя_поля = Выражение,
Имя_поля= Выражение [WHERE Условие_отбора]
Результатом выполнения этого оператора будет изменение шачений заданных полей для всех записей, удовлетворяющих услоЕию отбора. Выражение определяет новое значение указанного поля.
Пример изменения записей приведен ниже.
Дата добавления: 2014-12-01; просмотров: 986;