] Независимость от конкретной СУБД
Несмотря на наличие диалектов и различий в синтаксисе программ, содержащих SQL-запросы, они могут быть достаточно легко перенесены из одной СУБД в другую. Существуют системы, разработчики которых изначально ориентировались на применение по меньшей мере нескольких СУБД.
] Наличие стандартов
Наличие стандартов и набора тестов для выявления совместимости и соответствия конкретной реализации SQL общепринятому стандарту только способствует «стабилизации» языка.
] Декларативность
С помощью SQL программист описывает только то, какие данные нужно обработать. То, каким образом это сделать, решает СУБД непосредственно при обработке SQL-запроса. Однако программист при этом должен представлять, как СУБД будет разбирать текст его запроса. Чем сложнее сконструирован запрос, тем больше он допускает вариантов написания, различных по скорости выполнения, но одинаковых по итоговому набору данных.
Недостатки использования SQL
] Несоответствие реляционной модели данных
Создатели реляционной модели данных Э. Кодд, К. Дейт и их сторонники указывают на то, что SQL не является истинно реляционным языком. В частности, они указывают на следующие проблемы SQL [8]: Повторяющиеся строки Неопределённые значения (null) Явное указание порядка столбцов слева направо Столбцы без имени и дублирующиеся имена столблцы Отсутствие поддержки свойства «=» Использование указателей Высокая избыточность
] Сложность
Хотя SQL и задумывался как средство работы конечного пользователя, в конце концов он стал настолько сложным, что превратился в инструмент программиста.
] Отступления от стандартов
Несмотря на наличие международного стандарта ANSI SQL-92, многие компании, занимающиеся разработкой СУБД (например, Oracle, Sybase, Microsoft, MySQL AB), вносят изменения в SQL, применяемый в разрабатываемой СУБД, тем самым отступая от стандарта. Таким образом, появляются специфичные для каждой конкретной СУБД диалекты языка.
Структура языка
Основное и единственное назначение SQL - использование языка в написании запросов. Запрос SQL - команда на языке SQL, которую выполняет СУБД для получения необходимой информации из БД.
В зависимости от цели использования существуют 5 типов SQL- запросов [9]:
1. DDL (Data Definition Language - язык определения данных) позволяет:
* создавать (CREATE), изменять (ALTER), удалять (DROP) объекты БД (таблицы (TABLE), представления (VIEW), индексы (INDEX), последовательности (SEQUENCE), триггеры (TRIGGER) и др.);
* назначать (GRANT) и лишать (REVOKE) привилегий и ролей (ROLE) пользователей;
* анализировать (ANALYZE) информацию таблицы, индекса, кластера;
* проводить аудит (AUDIT) - процесс регистрации действий, производимых с объектами БД;
* добавлять комментарии (COMMENT) к объектам БД.
2. DML (Data Manipulation Language - язык манипулирования данных) позволяет получить доступ и манипулировать данными в существующих объектах БД (таблицах, представлениях):
* выбирать (SELECT);
* вставлять (INSERT);
* обновлять (UPDATE);
* удалять (DELETE);
* выполнять слияние (MERGE).
3. Transaction Control (управление транзакциями) позволяет управлять изменениями, сделанными в результате DML-запросов. Пользователь группирует DML-запросы (один или несколько) в логическую единицу, называемую транзакцией, которая является атомарной, т.е. выполняется либо целиком, либо не выполняется вовсе. Для того чтобы зафиксировать текущее состояние системы, используется точка сохранения, с целью возврата в любой следующий момент к зафиксированному с помощью нее (точки сохранения) состоянию. Благодаря использованию этого блока можно выполнять следующие действия:
* фиксировать (COMMIT) транзакции;
* откатывать (ROLLBACK) транзакции;
* устанавливать точки сохранения (SAVEPOINT).
4. Session Control (управление сессиями) позволяет динамически управлять свойствами текущей сессии пользователя:
* устанавливать роли (SET ROLE) пользователю, делать их доступными или недоступными;
* изменять настройки сессии (ALTER SESSION), например языковые, временные и др.;
5. System Control (управление системой) позволяет динамически управлять свойствами экземпляра БД (ALTER SYSTEM), например, изменять количество разделяемых серверов, убивать сессию и др. Необходимо отметить, что SQL широко используется как встроенный язык, т.е. SQL-запросы (DDL, DML, Transaction Control) включаются в программы, написанные на процедурных языках (например, Рго*С/С++, Pro*COBOL и др.); прекомпилятор Oracle интерпретирует встроенные SQL-запросы и переводит их в выражения, которые понятны компилятору процедурного языка.
Синтаксис записи формата запросов SQL
1. Слова, написанные прописными латинскими буквами, являются зарезервированными словами SQL.
2. Слова, написанные строчными буквами и заключенные в кавычки, именуют конструкцию, которую необходимо раскрыть дополнительно.
3. Слова, написанные строчными буквами и незаключенные в кавычки, именуют элементарное (не требующее дополнительного описания) понятие.
4. То же, что и 3., но ограниченное символами / является комментарием.
загменты, заключенные в фигурные скобки и разделенные являются альтернативными \ К При записи команды для конкретного применения необходимо выбрать одни из них.
6. Фрагмент, заключенный в квадратные скобки [ ], возможно не будет использоваться при записи команды для конкретного применения.
7. Круглые скобки () используются:
• в выражениях для изменения порядка выполнения операций;
• для объединения некоторых фрагментов в единое целое.
8. Многоточие, стоящее перед закрывающейся квадратной или круглой скобкой, означает, что заключенный в эти скобки фрагмент может быть повторен много раз.
5. Ф символом |
9. Символ:= служит для соединения левой раскрываемой части с раскрывающей ее правой частью и читается как «по определению есть»
Ниже рассмотрим синтаксис и примеры использования SQL- запросов типа DML, к числу которых относится запрос на выборку (SELECT).
Синтаксис запроса на выборку записей из таблицы БД имеет следующий вид:
SELECT {*| [{DISTINCTl AUJ] «выражение»[, «выражение»...]} [INTO список переменных включающего языка] FROM «ссылка на таблицу» [,«ссылка на таблицу»...] [WHERE [«условие соединения» [and «условие соединения»...]] «условие фильтра» [{and| OR} «условие фильтра»... ]]]/возможно применение круглых скобок для изменения порядка выполнения операции and и OR
[GROUP BY «столбец группировки» [,«столбец группировки»...]] [HAVING «условие фильтра»]
[ORDER BY «столбец упорядочения» [{ASC_| DESC}] [,«столбец упорядочения» [{ASC | DESC}]...]]
ALL выбор всех, в т.ч. дублируемых записей (по умолчанию) DISTINCT - исключаются дубли записей
«выражение»:= «первичный» | «первичный» «оператор» | «выражение»
«первичный»:= «имя столбца» | «литерал» | «функция агрегирования» | «встроенная константа» | «нестандартная функция» «имя столбца»:= [«ссылка на таблицу».]«идентификатор» «Оператор»:= +1 -1 /1 *
«Литерал»:= «строка»! математическое выражение «Строка»:= строка любых символов, заключенная в кавычки «Функция агрегирования»:= AVG («имя столбца») I COUNT (*)| COUNT ([{DISTINCTl ALL}] «имя столбца») | MIN («имя столбца») | МАХ («имя столбца»)] SUM («имя столбца») COUNT (*) /подсчет числа записей в группе/ COUNT ("имя столбца") /подсчет числа записей с NOT NULL значениями столбца.
«Ссылка на таблицу»: = «имя таблицы» [«алиас»] / алиас - синоним имени таблицы. Необходим при связывании таблицы самой с собой. Действует только на время выполнения команды «Имя таблицы»: = «идентификатор»
«идентификатор»:= буква [{буква| цифра | символ подчеркивания}...]
«Условие соединения»: = «имя столбца 1» «оператор сравнения» «имя столбца 2»
«Имя столбца 1» и «имя столбца 2»: = имена столбцов из связываемых таблиц, причем ссылка на таблицу, которой принадлежит столбец, обязательна
«Оператор сравнения»: = =| <| >| <=| >=| <>
«Условие фильтра»: = {«Выражение» «оператор сравнения» «выражение» | «Выражение» [NOT] BETWEEN «выражение» AND «Выражение» | «Выражение» [NOT] IN {«список значений» [ «подзапрос»}! «Имя столбца» [NOT] LIKE «образец» | «имя столбца» IS [NOT] NULlI Выражение» «оператор сравнения» {ALLl ANYl SOME} «подзапрос» [NOT] EXISTS «подзапрос»} «Подзапрос»: = SELECT...
В условии фильтра могут использоваться () для изменения порядка выполнения логических операторов, соединяющих элементарные условия фильтра.
«Столбец упорядочения»: = «имя столбца» из выражений фразы SELECT
«Столбец группировки»: = «имя столбца» из выражений фразы SELECT /группировка применяется для функций агрегирования/
Синтаксис запроса на создание таблицы БД: CREATE TABLE «имя таблицы» («имя столбца» «тип данных» [«размер»] [«ограничение на столбец»...] [«значение по умолчанию»] [,«имя столбца» «тип данных» [«размер»] [«ограничение на столбец»...] [«значение по умолчанию»]...] «ограничение на таблицу» [, «ограничение на таблицу»...])
"ограничение на столбец": = NOT NULL | UNIQUE | PRIMARY KEY | CHECK (условие)!
REFERENCES имя таблицы [(имя столбца)] /столбцы, являющиеся внешним ключом/ PRIMERY KEY и UNIQUE одинаковое действие на уникальность значения, а
PRIMERY KEY указывает на первичный ключ «Ограничение на таблицу»: = UNIQUE (список столбцов)| PRIMARY KEY (список столбцов)| /Не в стандарте / FOREIGN KEY (список столбцов)! REFERENCES имя таблицы [(список столбцов)] CHECK (условие)
«Условие» = «условие фильтра» /в случае ограничения на таблицу по нескольким столбцам/
«Значение по умолчанию»: = DEFAULT VALUE = «выражение»
Примеры запросов на выборку из следующих таблиц
Все примеры запросов SQL рассматриваются на примере структуры БД, состоящей из следующих таблиц (рис. 3.42).
день недели |
РАСПИСАНИЕ
номер | тип | день | номер | кор | ауди | Дис | вид | ФИО |
группы | не | не | заня | пус | то | цип | заня | препо |
дели | дели | тия | рия | лина | тии | давателя |
СТУДЕНТ
|
ДЕНЬ НЕДЕЛИ
номер дня недели
НЕДЕЛЯ
|
АУДИТОРИЯ
|
Рис. 3.42. Исходные таблицы для примеров запросов SQL |
Во всех приведенных примерах запросов SQL используются следующие правила:
Слова, написанные прописными латинскими буквами, являются зарезервированными словами SQL.
Слова, написанные строчными курсивными буквами, именуют конструкцию, которую необходимо раскрыть дополнительно. Запрос заканчивается знаком «;».
та В самом простом виде запрос представляет собой выбор (SELECT) всех строк по указанным столбцам из (FROM) таблицы и выглядит так:
SELECT имена столбцов FROM таблица;
Если необходимо вывести все столбцы таблицы, тогда используется знак * вместо перечисления всех имен столбцов.
SELECT * FROM таблица;
Например, вывести список дней недели и их номера:
SELECT день недели, номер дня недели FROM день недели;
Для вывода уникальных записей используется DISTINCT после SELECT и указывается имя столбца, по которому устанавливается уникальность записей.
Например, вывести список групп студентов, так как в таблице о студентах хранятся дублирующие значения групп (в одной группе учатся много студентов), то необходимо использовать DISTINCT:
SELECT DISTINCT группа FROM студент;
ти Можно задать ограничение на выбор определенных значений, указав после фразы WHERE условие на те столбцы, значения которых должны ему удовлетворять.
Условие может включать операторы сравнения (=,>,<,<>), логические выражения (true, false) и др. Условие должно возвращать логический результат (быть истинным или ложным). Условие может содержать несколько подусловий, которые соединяются между собой логическими операциями AND (и) и OR (или), и порядок выполнения подусловий можно изменять при помощи круглых скобок. Причем сначала выполняются операторы сравнения, затем AND и OR.
SELECT имена столбцов FROM название_таблицы WHERE условие;
Например, вывести информацию об аудиториях 19-го корпуса, в которых число мест больше 30:
SELECT аудитория, число_мест, состояние_доски FROM аудитория
WHERE корпус = ' 19' AND число_мест > 30;
Кроме того, в SQL существуют собственные операторы сравнения, к числу которых относятся:
* BETWEEN... AND... проверяет вхождение в диапазон значений, указанных между словом AND
* IN (list) - проверяет вхождение в указанный список значений
* LIKE - проверяет на соответствие с заданной маской
* IS NULL - проверяет, является ли неизвестным значением
Например, вывести информацию о студентах, учащиеся в группах, номер которых начинается на '7':
SELECT * FROM студент
WHERE номер_группы like '7%';
В маске знак _ означает любой символ; знак % означает любую последовательность символов.
Для каждого типа данных существуют набор функций для манипулирования значениями, к которому (типу) они относятся. Подробнее см. документацию.
Символьные функции:
Для преобразования регистра символов
* LOWER (все символы строчные)
* UPPER (все символы прописные)
* INITCAP (первая буква прописная, остальные строчные) Для манипулирования символами
* CONCAT (конкатенация - соединение двух строк в одну)
* SUBSTR (получение подстроки из строки)
* LENGTH (длина строки)
* INSTR (поиск подстроки в строке)
* TRIM (удаление символов с начала / конца строки)
* LPAD/RPAD (добавление символов с начала / конца строки до определенной длины)
* REPLACE (замена символов в строке)
Например, вывести все группы, в которых учатся Ивановы:
SELECT номер_группы, ФИО FROM студент
WHERE UPPER(SUBSTR(OHO,1,6)) like 'ИВАНОВ'; Функции для дат:
* MONTH_BETWEEN (получение числа месяцев между 2 датами)
* ADD_MONTH (добавление календарных месяцев к дате)
* NEXT_DAY (ближайшая дата, когда наступит заданный день недели)
* LAST_DAY (последняя дата текущего месяца)
* SYSDATE (текущая дата)
Например, вывести ближайшую дату от текущей даты, когда наступит пятница:
SELECT NEXT_DAY(SYSDATE, 'ПЯТНИЦА') FROM DUAL;
В этом запросе используется системная таблица Oracle DUAL, которая состоит из одного столбца DUMMY (фиктивный) и одной строки со значением 'X'; эта таблица используется для временного хранения констант, подсчета выражений, т.е. для возвращения однократного результата.
К числовым функциям относятся все математические операции над числами. Выполняя операции над значениями таблицы, получаем определенные результаты, которые необходимо вывести во фразе SELECT. Таким образом, результаты вычислений в виде выражений представляют собой вторичные данные.
Общие функции - это функции, которые одинаково работают для нескольких типов данных, к их числу относятся:
* TRUNC (усечение значения до заданной точности) - для дат и чисел
* ROUND (округление значения до заданной точности) - для дат и чисел
Например, вывести число мест, округленных до десятков, в аудиториях 19-го корпуса:
SELECT аудитория, ROUND (число_мест, -1) FROM аудитория
WHERE корпус - '19';
В функциях ROUND, TRUNC 2-ым аргументом выступает точность, которая представляет собой положительное число для округления (отсечения) десятичных знаков числа, и отрицательное число - для целой части числа, при этом значение точности (1, 2 и т.д.) зависит от отдаленности округления (отсечения) от точки (начала целой части), т.е. 1 - для десятых/-ков, 2 - для сотых/-ен и т.д.
ти Существует возможность отсортировать результаты запроса, указав после фразы ORDER BY, по каким столбцам (название столбца или его порядковый номер во фразе SELECT) в какой последовательности упорядочивать и способ упорядочивания: по возрастанию (ASC - по умолчанию) или убыванию (DESC).
SELECT имена_столбцов FROM таблица
ORDER BY имя(номер)_столбца способ^упорядочивания;
Например, вывести информацию о студентах группы 8521 упорядочение по ФИО в алфавитном порядке (т.е. по возрастанию) и в случае наличия студентов с одинаковым ФИО, сначала вывести студента с большим рейтингом (т.е. по убыванию).
SELECT номер_зачетки, ФИО, размер_стипендии, суммарный_рейтинг FROM студент
WHERE номер_группы - '8521'
ORDER BY ФИО, суммарный_рейтинг DESC;
ти Зачастую бывает необходимость представить значения в сгруппированном виде и применить групповые функции для каждой группы значений. Для этого используется фраза GROUP BY, в которой указаны названия столбцов, по которым группируются значения. В результате группировки все значения таблицы разбиваются по группам, которые указаны во фразе GROUP BY. К каждой полученной группе значений можно применить групповые функции: COUNT (подсчет количества значений), SUM (сумма значений), AVG (среднее значение), МАХ (максимальное значение), MIN (минимальное значение) (SUM, AVG применяются только к числовым значениям). При этом групповые функции можно использовать и без группировки, тогда все записи таблицы будут представлять одну группу. При использовании группировки во фразе SELECT перечисляются только те столбцы, по которым происходит группировка, или групповые функции к сгруппированным значениям, возвращаемое количество строк равно количеству полученных групп. Для исключения групп применяется фраза HAVING, в которой указывается условие для групповой функции. При этом для ограничения состава групп и других значений используется WHERE.
SELECT имена_группирующих_столбцов, групповые_функции(имя_столбца) FROM таблица
GROUP BY имена_группирующих_столбцов HAVING условие;
Например, вывести информацию о группах: номер группы (должен начинаться на '8' и упорядочен по возрастанию), количество в них студентов (должно быть больше 10 человек) и сумму размера стипендии по каждой группе.
SELECT номер_группы, соип1;(номер_зачетки), sum (размер_стипендии) FROM студент
WHERE номергруппы LIKE '8%' GROUP BY номер группы HAVING соип1:(номер_зачетки) >10
ORDER BY имя(номер) _столбца способ ^упорядочивания]
Порядок выполнения такого запроса следующий:
1) СУБД просматривает все записи из указанной таблицы во фразе FROM (всех студентов);
2) сравнивает значение указанного в условии столбца каждой записи с условием, указанном во фразе WHERE и выбирает только те записи, которые удовлетворяют этому условию (только тех студентов, которые учатся в группах, начинающихся на '8');
3) полученные записи группирует по столбцам, указанным во фразе GROUP BY (разбивает полученные записи о студентах на группы, начинающихся на '8');
4) из группированных записей выбирает только те, которые удовлетворяют условию во фразе HAVING (из полученных групп, начинающихся на '8', отбираются только те, у которых количество студентов больше 10 человек);
5) для каждой полученной группе выполняются групповые функции для сгруппированных записей, указанные во фразе SELECT (по каждой учебной группе кроме подсчета количества студентов вычисляется сумма размеров стипендий);
6) в последнюю очередь выполняется сортировка по тем столбцам или групповым функциям, которые указаны в ORDER BY (они должны обязательно входить в состав SELECT).
До сих пор рассматривались запросы, в которых происходит выборка только из одной таблицы. Далее рассмотрим примеры запросов для выбора данных из нескольких таблиц. В случае наличия одинаковых столбцов в 2-х таблицах для их различения и улучшения производительности работы с БД в запросах перед именем столбца указываются через точку имена таблиц. (Для одной таблицы СУБД автоматически расставляет имя таблицы для всех ее столбцов.) Иногда вместо имени таблицы используют алиас - это псевдоним, который назначается пользователем в самом запросе:
• таблицам - для краткости (чтобы каждый раз не писать полное имя) или для смысла (понятно для запоминания);
• столбцам, функциям или выражениям во фразе SELECT для отображения их названия в выводе результатов запроса.
Если происходит соединение нескольких таблиц и не указано условие, по которому их соединять, то образуется декартово произведение, т.е. все строки одной таблицы соединяются со всеми строками второй таблицы. Во избежание этого используется условие WHERE, при чем необходимо руководствоваться следующим правилом: для соединения п таблиц требуется, по крайней мере, (п-1) условий соединения.
В общем виде запрос из нескольких таблиц выглядит следующим образом:
SELECT таблица 1.столбец 1, таблица2.столбец 1, таблица2.столбец2, таблицаЗ. столбец 1
FROM таблица1, таблица2, таблица 3 WHERE таблица 1.столбец 1 = таблица2.столбец 1 AND таблица2.столбец2 = таблицаЗ. столбец 1;
Например, вывести расписание группы 8521 в порядке следования дней недели (для краткости таблиц используются алиасы).
SELECT р.тип_недели, р.день_недели, р.номер_занятия, р.корпус, р.аудитория, р.дисциплина, р.вид_занятий, р.ФИО_преподавателя FROM расписание р, день_недели дн
WHERE р.день_недели = дн.день_недели AND р.номер_группы = '8521' ORDER BY р.тип_недели, дн.номер_дня_недели, р.номер_занятия; Соединение между таблицами в запросах может быть 2-х типов:
* эквисоединение, когда соединение происходит по первичному и внешнему ключам таблиц. Приведенный выше пример относится к запросу такого типа.
* неэквисоединение, когда соединение между таблицами происходит по условию ограничения значений таблиц. Этот тип соединения используется редко, так как значения должны быть определены на одном домене и обязательно удовлетворять указанному условию.
В случае эквисоединения, когда в связующем столбце одной таблицы есть значение, которое отсутствует в связующем столбце другой таблицы, такое соединение является внешним. (В условии в скобках ставится + у того столбца, у которого отсутствует значение) Например, вывести расписание всех групп, даже тех, у которых не проводятся занятия (т.е. нет для них расписания).
SELECT р.*
FROM расписание р, студент с
WHERE р. номергруппы (+) = с. номергруппы
ORDER BY р.номер_группы, р.тип_недели, дн.номер_дня_недели, р.номер_занятия;
В случае эквисоединения, когда в связующем столбце одной таблицы есть значение, которое отсутствует в связующем столбце другой таблицы, такое соединение является внешним. (В условии ставится (+) у того столбца, у которого отсутствует значение) Например, вывести расписание всех групп, даже тех, у которых не проводятся занятия (т.е. нет для них расписания).
ид сотруд- ФИО ид руково |
СОТРУДНИК |
теля |
ника Рис 3.43. Связь типа петля вариант 3.6. д) |
Существуют ситуации, когда необходимо выполнить соединение таблицы с собой. Допустим, есть следующая структура таблицы, содержащая информацию о сотрудниках и их руководителей (кому они подчиняются), которые также являются сотрудниками, т.е. связь-петля таблицы с собой.
Например, если необходимо вывести список ФИО сотрудников и ФИО их руководителей, то запрос будет выглядеть так:
SELECT с.ФИО сотрудник, р.ФИО руководитель FROM сотрудник с, сотрудник р WHERE с.ид_руководителя = р.идсотрудника ORDER BY 1;
В таких запросах важную роль играют алиасы таблиц и столбцов для их семантического различения.
Выше в запросах на соединение нескольких таблиц использовался традиционный синтаксис по стандарту SQL-86, когда во фразе FROM через запятую перечисляются таблицы, а во фразе WHERE - условие, по которому их надо соединять. Стандарт ANSI SQL-92 предлагает другой вариант синтаксиса запросов на соединение таблиц: во фразе FROM указывается первая таблица, а далее во фразе JOIN указывается другая таблица и во фразе ON условие, по которому они соединяются. Для внешнего соединения вместо (+) используются слова LEFT/RIGHT для указания стороны, у которой отсутствует значение, или OUTER для обоих случаев [10]:
SELECT таблща1.столбец1, таблица2. столбец!, таблща2.столбец2 FROM таблица1
[LEFT/RIGHT/OUTER] JOIN таблица2 ON таблица 1.столбец 1 = таб- лица2. столбец1
[LEFT/RIGHT/OUTER] JOIN таблицаЗ ON таблица2.столбец2 = таблицаЗ. столбец1 WHERE условие;
Несмотря на то, что смысл самого запроса не поменялся, а это всего лишь другая запись, синтаксис, запроса, она имеет некоторые преимущества от традиционного:
] Вся информация о соединении всех таблиц располагается в одном месте. Чтобы отделить условия соединения от ограничений результатов запроса, больше не нужно формировать сложную фразу WHERE.
] Невозможно будет не описать условия соединения, так как СУБД потребует, чтобы использовался оператор ON или другой опера-
тор для явного описания условия соединения. Если требуется полное декартово произведение, то его необходимо задать явно. Например, вывести расписание занятий, проходящих в 19-ом корпусе в 507 аудитории в порядке следования дней недели (не выводить дни недели, когда нет занятий).
SELECT р.тип_недели, р.день_недели, р.номер_занятия, р номер группы, р.дисциплина, р.вид занятий, р.ФИО преподавателя FROM расписание р
JOIN день недели дн ON р.день недели = дн.день недели
WHERE р.корпус = ' 19' AND р.аудитория = '507'
ORDER BY р.тип недели, дн.номер дня недели, р.номерзанятия;
На практике достаточно часто бывает потребность в подзапросах, когда необходимо сначала получить промежуточный результат (подсчитать или вывести список), а затем использовать его для основного запроса. Синтаксис подзапроса следующий:
SELECT имена_столбцов
FROM таблица
WHERE выражение оператор
(SELECT имена столбцов FROM таблица WHERE условие)
Например, вывести ФИО всех студентов, которые учатся в одной группе с Ивановым Иван Ивановичем.
SELECT ФИО FROM студент
WHERE номер_группы - (SELECT номер_группы
FROM студент
WHERE ФИО = 'Иванов Иван Иванович'); Подзапрос - внутренний запрос, который заключен в скобки. Главный запрос - внешний относительно подзапроса.
При использовании подзапросов существуют следующие правила: —1 Подзапрос выполняется 1 раз до главного запроса. Результат подзапроса используется главным запросом. —1 Таблицы в главном запросе и в подзапросе могут как совпадать, так и различаться.
—1 Подзапрос должен находиться справа от оператора сравнения.
Однострочные подзапросы - возвращают как результат одну строку, используют однострочные операторы сравнения: =,<,>,<>. Приведенный выше пример относится к использованию однострочного подзапроса, так как предполагается, что студент может учиться только в 1 -ой группе.
Еще один пример однострочного подзапроса такой: вывести всех студентов, которые получают максимальную стипендию.
SELECT *
FROM студент
WHERE размерстипендии =
(SELECT шах(размер_стипендии) FROM студент);
Многострочные подзапросы - возвращают как результат более одной строки, используют многострочные операторы сравнения: IN - равно любому значению списка;
ANY - сравнение значения с любым значением, возвращаемым подзапросом;
ALL - сравнение значения с каждым значением, возвращаемым подзапросом.
Пример использования многострочного подзапроса следующий: вывести информацию о всех студентов, у кого стипендия выше, чем вся стипендия у студентов группы 8521:
SELECT * FROM студент
WHERE размер_стипендии > ALL
(SELECT размер_стипендии FROM студент