
- •Язык sql: манипулирование данными в этой лекции...
- •Введение в язык sql
- •Назначение языка sql
- •История языка sql
- •Особая роль языка sql
- •Используемая терминология
- •Запись операторов sql
- •Манипулирование данными
- •Литералы
- •Простые запросы
- •Выборка строк, конструкция where
- •Сортировка результатов, конструкция order by
- •5.3.3. Использование агрегирующих функций языка sql
- •Глава 5. Язык sql: манипулирование данными 183
- •5.3.5. Подзапросы
- •Глава 5. Язык sql: манипулирование данными 189
- •5.3.6. Ключевые слова any и all
- •5.3.8. Ключевые слова exists и not exist
- •Глава 5. Язык sql: манипулирование данными 203
Выборка строк, конструкция where
В приведенных выше примерах в результате выполнения операторов SELECT выбирались все строки указанной таблицы. Однако очень часто требуется тем или иным образом ограничить набор строк, помещаемых в результирующую таблицу запроса. Это достигается с помощью указания в запросе конструкции WHERE.
Данная конструкция состоит из ключевого слова WHERE, за которым следует перечень условий поиска - предикат, определяющий те строки, которые должны быть выбраны при выполнении запроса.
Конструкция WHERE эквивалентна операции выборки реляционной алгебры. Причём конструкция используется для горизонтальной и вертикальной выборок, а так же может их сочетать.
В конструкции WHERE существует пять основных типов условий поиска или предикатов, если пользоваться терминологией ISO для указания ограничений накладываемых на запрос.
Это такие предикаты, как:
Сравнение. Сравниваются результаты вычисления одного выражения с результатами вычисления другого выражения.
Диапазон. Проверяется, попадает ли результат вычисления выражения в заданный диапазон значений.
Принадлежность к множеству. Проверяется, принадлежит ли результат вычисления выражения к заданному множеству значений.
Соответствие шаблону. Проверяется, отвечает ли некоторое строковое значение заданному шаблону.
Значение NULL. Проверяется, содержит ли данный столбец NULL - неопределенное значение.
Рассмотрим примеры использования всех указанных типов условий поиска.
Пример 5. Условие поиска путем сравнения
Перечислить всех сотрудников, которые родились после 1950 года.
SELECT [Фамилия], [Имя], [Отчество], [Дата рождения]
FROM [Список сотрудников]
WHERE [Дата рождения] >= ‘01/01/1950’
В этом запросе используются таблица [Список сотрудников] и предикат [Дата рождения] >= ‘01/01/1950’. При выполнении запроса будет создана новая таблица, содержащая только те строки таблицы [Список сотрудников], в которых значение столбца [Дата рождения] больше ‘01/01/1950’. Результаты выполнения запроса представлены в таблице 6.
Результат выполнения запроса из примера 5
Таблица 6.
-
Фамилия
Имя
Отчество
Дата рождения
Иванов
Иван
Иванович
1.01.1970
Варежкина
Наталья
Николаевна
1.04.1975
Сидоров
Иван
Петрович
15.05.1980
Савельев
Евгений
Андреевич
24.07.1980
В условиях поиска могут встречаться различные операции сравнения. Эти операции приведены в таблице 7.
Более сложные предикаты могут быть построены с помощью логических операций AND, OR или NOT, а также с помощью скобок, используемых для определения порядка вычисления выражения, если это необходимо или желательно.
Вычисление выражений в условиях выполняется по следующим правилам.
Выражение вычисляется слева направо.
Первыми вычисляются подвыражения в скобках.
Операции NOT выполняются перед операциями AND и OR.
Операции AND выполняются перед операциями OR.
Для устранения любой возможной неоднозначности рекомендуется использовать круглые скобки, в противном случае необходимо соблюдать приоритет логических операций.
Операции сравнения
Таблица 7.
Знак операции |
Назначение |
= |
Равно |
<> |
Не равно (стандарт ISO) |
!= |
Не равно (диалекты SQL) |
< |
Меньше |
> |
Больше |
<= |
Меньше или равно |
>= |
Больше или равно |
Пример 6. Сложные условия поиска
Требуется перечислить всех сотрудников с именами Иван и Наталья.
SELECT [Фамилия], [Имя], [Отчество], [Дата рождения]
FROM [Список сотрудников]
WHERE [Имя]= ‘Иван’ OR [Имя]= ‘Наталья’
Результат выполнения запроса из примера 6
Таблица 8.
-
Фамилия
Имя
Отчество
Дата рождения
Иванов
Иван
Иванович
1.01.1970
Варежкина
Наталья
Николаевна
1.04.1975
Сидоров
Иван
Петрович
15.05.1980
Пример 7. Использование диапазонов (BETWEEN/NOT BETWEEN) в условиях поиска
Перечислить всех сотрудников, которые родились в интервале с 1970 по 1981 года.
SELECT [Фамилия], [Имя], [Отчество], [Дата рождения]
FROM [Список сотрудников]
WHERE [Дата рождения] BETWEEN ‘01/01/1970’ AND ‘01/01/1981’
В этом запросе используются таблица [Список сотрудников] и предикат по полю [Дата рождения] с использованием ключевого слова BETWEEN. При выполнении запроса будет создана новая таблица, содержащая только те строки таблицы [Список сотрудников], в которых значение столбца [Дата рождения] больше ‘01/01/1970’ и меньше ‘01/01/1981’. Результаты выполнения запроса представлены в таблице 9.
Результат выполнения запроса из примера 7
Таблица 9.
-
Фамилия
Имя
Отчество
Дата рождения
Иванов
Иван
Иванович
1.01.1970
Варежкина
Наталья
Николаевна
1.04.1975
Сидоров
Иван
Петрович
15.05.1980
Савельев
Евгений
Андреевич
24.07.1980
Существует также версия проверки диапазона значений, которая имеет противоположный смысл (NOT BETWEEN), В этом случае требуется, чтобы проверяемое значение лежало вне границ заданного диапазона.
Наличие ключевого слова BETWEEN и соответствующей проверки лишь незначительно повышает выразительную мощность языка SQL, поскольку те же результаты могут быть достигнуты с помощью выполнения двух обычных проверок.
В результате приведенный выше запрос можно представить следующим образом:
SELECT [Фамилия], [Имя], [Отчество], [Дата рождения]
FROM [Список сотрудников]
WHERE [Дата рождения] >=‘01/01/1970’ AND [Дата рождения] <=‘ ‘01/01/1981’
Однако многие полагают, что проверка принадлежности к диапазону с помощью ключевого слова BETWEEN является более простым способом записи условий выборки, чем обычные проверки.
Пример 8. Условия поиска с проверкой принадлежности к множеству (IN/NOT IN)
Требуется отыскать всех сотрудников, фамилии которых Иванов, Петров и Сидоров.
SELECT [Фамилия], [Имя], [Отчество]
FROM [Список сотрудников]
WHERE [Фамилия] IN (‘Иванов’, ‘Петров’, ‘Сидоров’);
Проверка принадлежности к множеству обеспечивается с помощью ключевого слова IN. При этом проверяется, соответствует ли результат вычисления выражения одному из значений в предоставленном списке — в нашем случае это строки ‘Иванов’, ‘Петров’, ‘Сидоров’.
Результаты выполнения запроса представлены в таблице 10. Существует также версия такой проверки, имеющая противоположный смысл (NOT IN), которая используется для отбора любых значений, кроме тех, которые указаны в представленном списке.
Как и оператор BETWEEN, оператор IN незначительно повышает выразительную мощность языка SQL — тот же самый запрос может быть представлен следующим образом:
SELECT [Фамилия], [Имя], [Отчество]
FROM [Список сотрудников]
WHERE [Фамилия] = ‘Иванов’ OR [Фамилия] = ‘Петров’ OR [Фамилия] = ‘Сидоров’;
Однако использование оператора IN представляет собой более эффективный способ записи условий поиска, особенно если набор допустимых значений достаточно велик.
Результат выполнения запроса из примера 8
Таблица 10.
-
Фамилия
Имя
Отчество
Иванов
Иван
Иванович
Петров
Евгений
Ильич
Сидоров
Иван
Петрович
Пример 9. Условия поиска с указанием шаблонов (LIKE/NOT LIKE)
Требуется вывести список всех сотрудников, в отчестве которых присутствуют символ «е» в любом части этого слова.
SELECT [Фамилия], [Имя], [Отчество]
FROM [Список сотрудников]
WHERE [Отчество] LIKE ‘%е%’;
При выполнении данного запроса необходимо организовать поиск строки содержащей символ ‘е’, который может находиться в любом месте значений столбца [Отчество] таблицы [Список сотрудников].
В языке SQL существуют два специальных символа шаблона, используемых при проверке символьных значений.
«%» - символ процента представляет любую последовательность из нуля или более символов, поэтому часто именуется также подстановочным символом.
«_» - символ подчеркивания представляет любой отдельный символ.
Все остальные символы в шаблоне представляют сами себя. Если требуемая строка должна включать также служебный символ, обычно применяемый в качестве символа подстановки, то следует определить с помощью конструкции ESCAPE "маскирующий" символ, который указывает, что следующий за ним символ больше не имеет специального значения, и поместить его перед символом подстановки.
Результат выполнения запроса из примера 9
Таблица 11
-
Фамилия
Имя
Отчество
Варежкина
Наталья
Николаевна
Сидоров
Иван
Петрович
Савельев
Евгений
Андреевич
Например, для проверки значений на соответствие литеральной строке «15%» можно воспользоваться таким предикатом:
LIKE '15#%' ESCAPE '#'
Пример 10. Использование значения NULL в условиях поиска (IS NULL/IS NOT NULL)
Требуется показать всех сотрудников, которые не уволены на данный момент времени
Для визуализации данного примера используем ещё одну исходную таблицу «Принятие сотрудников на должность». Для упрощения восприятия используем ненормализованную таблицу 12.
Принятие сотрудников на должность
Таблица 12
№ п. п. |
Фамилия |
Имя |
Отчество |
Дата рождения |
Дата приёма |
Должность |
Дата увольнения |
Причина |
1 |
Кошечкин |
Степан |
Николаевич |
1.1.1990 |
3.12.2009 |
Слесарь |
|
|
2 |
Реброва |
Маргарита |
Александровна |
3.12.1973 |
3.12.2003 |
Помощник редактора |
15.12.2010 |
Переведена на должность гл. Редактора |
3 |
Реброва |
Маргарита |
Александровна |
3.12.1973 |
15.12.2010 |
Гл. Редактор |
|
|
4 |
Валуев |
Максим |
Александрович |
10.03.1960 |
10.05.2007 |
Программист |
|
|
5 |
Петькин |
Андрей |
Иванович |
3.07.1971 |
15.05.2008 |
Директор |
|
|
6 |
Суворов |
Андрей |
Михайлович |
4.10.45 |
10.10.2003 |
Директор |
15.05.2008 |
Уволен по собственному желанию |
7 |
Булатов |
Максим |
Николаевич |
3.12.1973 |
1.1.2003 |
Программист |
10.05.2007 |
Уволен по собственному желанию |
8 |
Ридик |
Семён |
Михайлович |
12.08.1998 |
3.5.2008 |
Сторож |
|
|
Просматривая таблицу 12, можно заметить, что в ней отсутствуют сведения об увольнении у некоторых сотрудников. На основании этого простого примера можно прийти к заключению, что третью из этих записей можно выбрать с помощью следующего предиката:
[Фамилия] = ‘Реброва’ AND [Дата увольнения] = ‘’
Однако это решение ошибочно. Отсутствующая дата увольнения имеет значение «NULL», которое рассматривается как неопределенное значение, поэтому нельзя определить его равенство или неравенство с другой строкой. Если попробовать выполнить запрос с приведенным предикатом, то результирующая таблица окажется пустой. Правильное решение состоит в явной проверке на наличие пустого значения, для чего используется специальное ключевое слово «IS NULL»:
SELECT [Фамилия], [Имя], [Отчество], [Должность]
FROM [Принятие сотрудников на должность]
WHERE [Фамилия] = ‘Реброва’ AND [Дата увольнения] IS NULL;
Для проверки присутствия в столбце значений, отличных от NULL, может использоваться версия данного условия поиска, которая имеет противоположный СМЫСЛ (IS NOT NULL).