□ Предложение FROM таблицы задает таблицы, из которых надлежит извлекать строки. Если указано имя более чем одной таблицы, следует выполнить соединение.
Ссылку на таблицу можно заменить псевдонимом, используя имя таблицы [AS] псевдоним.
□ Предложение WHERE включает набор условий для отбора строк.
WHERE [NOT] условие_1 [[AND|OR][NOT] условие_2]...
где условие_1, _2 ... – одна из следующих конструкций:
выражение { = | <> | < | <= | > | >= } { значение | ( подзапрос ) }
выражение [NOT] BETWEEN значение_2 AND значение_3
выражение [NOT] IN { ( константа_1 [,константа_2]... ) | ( подзапрос ) }
выражение IS [NOT] NULL
выражение [NOT] LIKE 'шаблон'
EXISTS ( подзапрос )
Выражения в WHERE строятся по тем же правилам, что и в select_выражениях.
□ Предложение GROUP BY используется для определения групп выходных строк, к которым могут применяться агрегатные функции. Если это предложение отсутствует и используются агрегатные функции, то все столбцы с именами, упомянутыми в SELECT, должны быть включены в агрегатные функции, и эти функции будут применяться ко всему набору строк, которые удовлетворяют запросу. В противном случае все столбцы списка SELECT, не вошедшие в агрегатную функцию, должны быть сгруппированы с помощью предложения GROUP BY. Все выходные строки запроса, которые сгруппированы по равенству значений столбцов, образуют единую группу. Далее к этим группам применяются агрегатные функции (SUM, COUNT, AVG, MIN или MAX), указанные во предложении SELECT, что приводит к замене всех значений группы на единственное значение (сумма, количество, среднее, минимальное или максимальное значение).
□ С помощью предложения HAVING можно включать дополнительное условие отбора. Конструкция HAVING очень похожа на WHERE, однако если предложение WHERE определяет предикат для фильтрации строк, то предложение HAVING применяется после группировки для определения аналогичного предиката, фильтрующего группы по значениям агрегатных функций. Это предложение необходимо для проверки значений, которые получены с помощью агрегатной функции не из отдельных строк таблиц, указанных в предложении FROM, а из групп таких строк. Поэтому такая проверка не может содержаться в предложении WHERE.
□ Предложение UNION включает все выходные строки каждого из запросов. Если определен параметр ALL, то сохраняются все дубликаты выходных строк, в противном случае оставляется только одна строка.
□ С помощью предложения ORDER BY можно расположить результаты одного или нескольких запросов в определенном порядке. Строки сортируются в соответствии со значениями столбцов, указанных в списке. Первый столбец имеет наивысший приоритет, второй столбец задает порядок сортировки дублируемых значений первого столбца, третий столбец вступает в действие, если совпадают значения во втором столбце, и т.д. Можно задать параметр сортировки ASC (по возрастанию, используется по умолчанию) или DESC (по убыванию) отдельно для каждого столбца. Сортировка набора символов будет осуществляться в соответствии с его упорядочивающей последовательностью. Вместо имен столбцов можно указывать целые числа. Эти числа указывают на местоположение столбца в выходных данных, так что 1 будет указывать на первый столбец, а 5 – на пятый столбец и т.д. Если выходные столбцы не имеют имен, то будут использоваться номера.
C l i e n t s
ID_NUM | NAME | CITY | AGE |
1809 | Иванов | Москва | 45 |
1996 | Петров | Нижний Новгород | 39 |
1777 | Сидоров | Рязань | 21 |
Если нужно получить все данные о заказчиках из Твери, включенных в таблицу Clients, необходимо воспользоваться оператором SELECT для формирования следующего запроса:
SELECT *
FROM Clients
WHERE City = 'Тверь'
Первая строка означает "выбери все столбцы", а предложение FROM указывает на таблицу, из которой они должны быть выбраны. С помощью WHERE запрашиваем не просто конкретную строку, а все строки, которые удовлетворяют указанному условию (ассоциируются с Тверью). Не имеет никакого значения, сколько заказчиков из Твери записано в таблице - ни одного или десять тысяч. Все записи будут получены с помощью этого оператора.
Другие примеры:
□ Найти только имена заказчиков из Твери, возраст которых превышает 40 лет.
SELECT Name FROM Clients WHERE City = 'Тверь' AND Age > 40
□ Найти данные о всех заказчиках, фамилии которых начинаются на букву «И»
SELECT * FROM Clients WHERE Name LIKE 'И%'
Здесь в выражении WHERE использовалось сравнение с шаблоном 'И%'. Знак % заменяет последовательность произвольной длины любых символов.
□ Показать год рождения каждого заказчика
SELECT Name, (2005-AGE) AS BirthYear FROM Clients
Год рождения - вычисляемый столбец, для обозначения нового столбца использован псевдоним BirthYear.
□ Показать, города, где проживают заказчики.
SELECT DISTINCT City FROM Clients
□ Вычислить средний возраст заказчиков из Москвы
SELECT AVG(AGE) AS AvgAge FROM Clients WHERE City = 'Москва'
В запросе используется агрегатная функция AVG() для вычисления среднего значения в столбце AGE среди строк, где City = 'Москва'. В результате, при любом количестве заказчиков из разных городов, получится таблица, состоящая из из одной строки и одного столбца.
□ Показать, сколько заказчиков в каждом городе
SELECT City, COUNT(*) AS Client_Count FROM Clients GROUP BY City
В запросе применяется группировка. Здесь все записи из таблицы разбиваются на группы с одинаковыми названиями городов GROUP BY City, и в каждой группе вычисляется количество строк COUNT(*).
□ Показать города, где количество заказчиков не превышает 10
SELECT City, COUNT(*) AS Client_Count FROM Clients
GROUP BY City HAVING COUNT(*)<=10
□ Определит количество заказчиков в каждом городе можно только с помощью группировки, поэтому ограничение на количество заказчиков можно вводить только в HAVING, а не в WHERE.
□ Найти самых молодых заказчиков
SELECT * FROM Clients WHERE Age = (SELECT MIN(Age) FROM Clients)
Здесь используется вложенный запрос (подзапрос) в условии WHERE. Подзапрос возвращает минимальный возраст среди всех заказчиков. Внешний запрос выводит данные о заказчиках, возраст которых равен минимальному.
□ Найти самых молодых и самых пожилых заказчиков
SELECT * FROM Clients WHERE Age = (SELECT MIN(Age) FROM Clients)
UNION
SELECT * FROM Clients WHERE Age = (SELECT MAX(Age) FROM Clients)
Запрос построен как объединение UNION двух запросов. Первый находит самых молодых, второй – самых пожилых заказчиков. В случае, если в таблице все заказчики одного возраста, то в получаемой выборке не будет дублирования, т.к. UNION здесь используется без ALL.
С помощью предложения SELECT можно реализовать любую операцию реляционной алгебры.
□ Выборка (горизонтальное подмножество) таблицы создается из тех ее строк, которые удовлетворяют заданным условиям. Пример:
SELECT *
FROM Clients
WHERE City = 'Тверь'
□ Проекция (вертикальное подмножество) таблицы создается из указанных ее столбцов (в заданном порядке) с последующим исключением избыточных дубликатов строк. Пример:
SELECT DISTINCT City FROM Clients
□ Объединение двух таблиц содержит те строки, которые есть либо в первой, либо во второй, либо в обеих таблицах. Пример:
SELECT * FROM Clients WHERE Age = (SELECT MIN(Age) FROM Clients)
UNION
SELECT * FROM Clients WHERE Age = (SELECT MAX(Age) FROM Clients)
□ Пересечение двух таблиц содержит только те строки, которые есть и в первой, и во второй. Пример:
SELECT * FROM Clients WHERE Age IN (SELECT MIN(Age) FROM Clients)
□ Разность двух таблиц содержит только те строки, которые есть в первой, но отсутствуют во второй. Пример:
SELECT * FROM Clients WHERE City NOT IN
(SELECT City FROM Clients GROUP BY City HAVING Count(*)<=10)
□ Декартово произведение таблиц и различные виды соединений рассмотрены ниже.
Когда в предложении FROM указаны несколько таблиц, то все они неявно считаются соединяемыми. По сути это означает, что можно получить все возможные комбинации строк (по одной из каждой таблицы), и именно с такой конкатенацией будут работать остальные операторы запроса. Эта конкатенированная таблица носит название декартово произведение или перекрестное соединение (cross join). Чаще всего пользователю нужно исключить большинство строк и выделить определенные данные, что обычно реализуется посредством установления отношений (или условий) при помощи предложения WHERE. Другой способ установить отношения – использование встроенных операций соединения, чтобы осуществить внутреннее соединение в предложении FROM. Результат этого соединения есть порожденная таблица, которая и должна обрабатываться остальными операторами запроса.
Допускаются перекрестные (CROSS), естественные (NATURAL) соединения, т.е. соединения по нескольким столбцам с одинаковыми именами, и соединения типа «объединений» (UNION). Соединение UNION и оператор UNION являются различными понятиями. Оператор UNION служит для объединения выходных данных нескольких операторов SELECT.
перекрестное соединение:
таблица A CROSS JOIN таблица B
естественное соединение:
таблица A [NATURAL] [тип соединения] JOIN таблица B
соединение объединения:
таблица A UNION JOIN таблица B
объединение посредством предиката:
таблица A [тип соединения] JOIN таблица B ON предикат
объединение посредством имен столбцов:
таблица A [тип соединения] JOIN таблица B USING (имя столбца,..)
тип соединения:
INNER|{{LEFT|RIGHT|FULL|[OUTER]}
Все эти структуры служат для того, чтобы заместить имя таблицы в предложении FROM. Хотя в перечне приведен синтаксис соединений, которые используют только две таблицы, можно соединять любое их количество. Результатом соединения является таблица, которая обрабатывается в качестве исходной остальными операторами запроса.
Ключевое слово OUTER (внешний) не является обязательным, оно употребляется только для уточнения и не используется ни в каких операциях с данными.
CROSS – перекрестное соединение. Это простое декартово произведение. Используются все комбинации строк. Пример перекрестного соединения приведен в таблице 2.2.
INNER – внутреннее соединение. Это тип соединения по умолчанию, оно используется, когда другой тип соединения не задан. Соединяются только те строки, где найдены совпадающие значения столбца. Внутреннее соединение иллюстрируется в таблице 2.3.