4.4.2. Инструкция SELECT Все запросы на получение практически любого количества данных из одной или нескольких таблиц выполняются с помощью единственного предложения SELECT. В общем случае результатом реализации предложения SELECT является другая таблица (но в общем случае набор кортежей, а не отношение, так как здесь в таблице могут быть одинаковые строки - то есть в этом пункте таблица и отно - шение - разные понятия). В этой новой (рабочей) таблице может быть снова применена операция SELECT и т.д., т.е. такие операции могут быть вложены друг в друга. Представляет исторический интерес тот факт, что именно возможность включения одного предложения SELECT внутрь другого послужила мотивировкой использования прилагательного "структуризированный" в названии языка SQL. В тоже время, к сожалению, не во всех реализациях допускается вложенность запросов. Детально изучить синтаксис команды Select, можно используя [4, 14, 24, 36]. Здесь же рассмотрим существенные элементы синтаксиса (используется форма Бэкуса-Науэра, подробнее см. [5]). <cursor specification>:=<query expression>[<order by clause>] <query expression>:=<query term>|(<query expression>UNION[ALL]<query term>) <query term>:=<query specification>|<query expression> <query specification>:=SELECT[ALL|DISTINCT]<select list><table expression> <table expression>:=<from clause>[<where clause>][<group by clause><having clause>]
|
Поясним используемые термины. 1. <cursor specification> - есть спецификация курсора. Курсор - этот средство языка SQL, позволяющее получить последовательный доступ к результату запроса в БД. Дело в том, что многие реализации SQL позволяют производить навигационные операции с курсорами. 2. <query expression> - выражение запроса 3. <order by clause> - инструмент для упорядочивания кортежей в курсоре (результате). 4. <query term> - элементарная логическая единица запроса. Запрос может состоять из нескольких термов, связанных операцией объединения UNION. Каждый терм может состоять из более мелких термов, и т.д. <query specification> - это терм самого низкого уровня, представляющий из себя оператор SELECT. Здесь указывается <select list> - список атрибутов, которые войдут в результат, т.е. SELECT здесь не только отбирает записи согласно табличному выражению <table expression>, а еще и выбирает только нужные атрибуты, т.е. выполняется проекция, однако в ходе нее дубликаты по умолчанию не удаляются; если же их надо удалить, то необходимо указать ключевое слово DISTINCT, в этом случае проекция будет работать также, как и в реляционной алгебре. Табличное выражение <table expression^ по сути, есть условие для отбора. Оно содержит <from clause>, представляющим собой ключевое слово FROM и источник, это может быть либо отношение из БД, либо спецификация другого курсора. Также надо указывать переменную, по которой затем можно будет обращаться к источнику. Итак, <from clause>:=FROM (<relation name>|<cursor spe- cifcation>) <variable> Необязательные элементы <where clause>, <having clause> и <group by clause> служат для задания дополнительных условий на выбирае - мые кортежи. <where clause> состоит из ключевого слова WHERE и логического условия на отбираемые данные, логическое условие состоит из операторов сравнения (>,<,=,<>,>=,<=) и проверок на принадлежность курсору или на вхождение одного курсора в другой (IS IN).; <groub by close> и <having by close> используются для задания условий не на один конкретный атрибут, а сразу на группу атрибутов, которые указываются после ключевого слова GROUP. Затем следует ключевое слово HAVING после которого следует условие, причем можно использовать только те имена атрибутов, которые указаны в GROUP BY, а остальные только в функциях агрегирования (min - минимум, max - максимум, avg - среднее значение, ^unt - количество, sum - сумма). На практике, конструкции языка SQL удобнее изучать на примерах, так как, несмотря на сложный синтаксис, в большинстве случаев применяются достаточно простые запросы. Пример 1. Найти всех преподавателей старше 40 лет Приведем запрос в двух формах - с использованием короткого псевдонима для именования таблицы и без использования псевдонима: A) SELECT * FROM ПРЕПОДАВАТЕЛИ P WHERE Г.возраст>4 0 B) SELECT * FROM ПРЕПОДАВАТЕЛИ WHERE ПРЕПОДАВАТЕЛИ.возраст>4 0 Поскольку запрос работает только с одной таблицей, допустимо и отсутствие имени таблицы (отношения). SELECT * FROM ПРЕПОДАВАТЕЛИ WHERE возраст>4 0
|
Пример 2. Определим декана ФМФ SELECT фио_декана FROM ФАКУЛЬТЕТЫ WHERE назв_фак='ФМФ' Обратим внимание, что в этом случае фактически выполняется 2 операции реляционной алгебры - проекция и селекция. Пример 3. Выбрать преподавателей ФМФ (все атрибуты), получающих зарплату больше 15000 р. и отсортировать их по фамилиям. Рассмотрим несколько вариантов реализации запроса. A) Использование операции соединения в запросе явным образом SELECT P.id, P-ФИО, P-возраст, P-стаж FROM ПРЕПОДАВАТЕЛИ P INNER JOIN БЫТЬ_СОТР B INNER JOIN КАФЕДРЫ K INNER JOIN ФАКУЛЬТЕТЫ F) ON ( (P.id=B.id_преп)AND(B.id_каф=K.id)AND(K.id_фак=F.id) WHERE (F.названйе='ФМФ')AND(в7з/п>15000) _ ORDER BY P.ФИО Примечание. 1. Операция JOIN предполагает вычисление
произведения таблиц, а операция INNER JOIN - соединение, при этом
возможно либо указать с помощью конструкции USING столбцы, ко¬торый
присутствует в двух или более таблицах (в этом случае условие
соединения - равен¬ство значений в этом столбце в обоих таблицах) ,
или с помощью конструкции ON (в этом случае указывается в явном виде
условие объединения), как в нашем примере. |
B) Использование соединения в автоматическом режиме (запрос к нескольким таблицам) SELECT P.id, P-ФИО, P-возраст, P-стаж FROM ПРЕПОДАВАТЕЛИ P, БЫТЬ_СОТР B, КАФЕДРЫ K, ФАКУЛЬТЕТЫ F WHERE (P.id=B.id_преп)AND(B.id_каф=K.id)AND (K.id_фак=F.id)AND(F. название=' ФМФ')АШ(В. з/п>15000) ORDER BY P.ФИО C) Использование вложенных конструкций SELECT * FROM ПРЕПОДАВАТЕЛИ WHERE id IS IN ( SELECT id_преп FROM БЫТЬ_СОТР WHERE (з/п>2000) AND (id_^ IS IN ( SELECT id_каф FROM КАФЕДРЫ WHERE id_фак IS IN ( SELECT id FROM ФАКУЛЬТЕТЫ WHERE назв='ФМФ' )ORDER BY ФИО Пример 4. Вычислить средний возраст преподавателей. Используется функция агрегирования AVG. SELECT AVG(возраст) FROM ПРЕПОДАВАТЕЛИ Пример 5. Определить названия тех кафедр, на которых работает более 15 преподавателей. Используется функция агрегирования COUNT. SELECT назв. каф FROM (КАФЕДРЫ JOIN БЫТЬ_СОТР ON id=id_каф) GROUP BY id_каф HAVING C0UNT(ФИ0_преп)>15
|
Пример 6. Вычислить число преподавателей на каждой кафедре. Здесь следует использовать функцию агрегирования COUNT внутри HAVING. SELECT назв_каф, C0UNT(ФИ0_преп) FROM (КАФЕДРЫ JOIN БЫТЬ_СОТР ON id=id_каф) GROUP BY id_каф Из примеров 4-6 видно, что, в отличие от реляционной алгебры, SQL позволяет в рамках оператора выборки фактически одновременно производить манипулирование выбранными данными, т.е. выполняются операции реляционной алгебры над исходными отношениями и операции над содержимым результирующих таблиц, что предполагает скрытые навигационые возможности. В стандартном SQL также присутствует механизм курсоров, явно реализующий построчный доступ к результатам запроса, что делает SQL одновременно спецификационным и навигационным языком. Более подробно с возможностями выборки данных в SQL можно ознакомится в [4, 14, 24, 36]. Возможности конкретных реализаций SQL следует изучать по документации соответствующих сред. |