5.5.4. Логические выражения в условии sql-операторов
Когда выше обсуждались SQL-операторы и, в частности, раздел WHERE (условие), то были перечислены лишь некоторые возможные способы задания условия на выбираемые записи. В частности, были упомянуты операции сравнения (больше, меньше и т.д.) и логические связки (и, или, не). В условии поиска (в разделе WHERE) операторов SELECT, UPDATE и DELETE можно использовать и более интересные логические выражения.
Сопоставление текстовых полей с образцом
Для сравнения текстовых строк с образцом существуют логические операции LIKE и MATCHES. Операция LIKE обладает несколько меньшими возможностями по сравнению с MATCHES, поэтому рассматриваться не будет. Формат операции MATCHES:
<имя поля> MATCHES <образец>
Образец для оператора MATCHES является текстовой строкой и строится по следующим правилам:
специальный символ '*' соответсвует произвольной последовательности из 0 или более символов;
специальный символ '?' соответсвует одному произвольному символу;
символы внутри квадратных скобок ([...]) позволяют задавать удовлетворяющие образцу символы (например, [абв] или [аеиуюыя]) диапазон символов через дефис (например, [А-Я] или [0-9]), или с помощью символа '^' указывать те символы, которые не удовлетворяют образцу (например, [^абв]);
специальный символ '\' отменяет значение специального символа, указанного за '\', например '\*' означает именно символ '*', а не произвольную последовательность символов;
все другие символы являются обычными и должны соответсвовать символам из сравниваемой строки.
Например, по следующему запросу
SELECT person_id FROM persons WHERE lname MATCHES "[Бб]ендер"
будут выбраны номера записей (значения поля person_id) для лиц с фамилиями "Бендер" и "бендер".
Если нам требуется отобрать все записи о товарах из таблицы items, в названии которых присутствует слово "грибы" (например, "Соленые грибы", "Грибы по-французски", "Грибы-мухоморы маринованные"), то такую задачу решает следующий запрос:
SELECT item_id FROM items WHERE name MATCHES "*[Гг]рибы*"
Операцию MATCHES, как и любую другую, можно использовать вместе с другими логическими операциями путем использования логических связок OR/NOT/AND и скобок:
SELECT item_id FROM items WHERE (name MATCHES "теннис") AND price > 20.00
Проверка на вхождение в множество
Но самая, пожалуй, мощная логическая операция, которую можно использовать в условии для операторов SELECT, UPDATE и DELETE это операция IN. Эта логическая операция возвращает истину, когда значение слева от слова IN входит в множество значений, указанное справа от слова IN. Множество возможный значений может быть указано явно - через запятую в скобках, а может формроваться другим оператором SELECT:
<выражение> IN (<значение 1>, <значение 2>, ....)
<выражение> IN (<оператор SELECT>)
Например, если мы хотим получить адреса фирм "АО Рога и Копыта" и "ТОО Добро пожаловать", то должны выполнить следующий запрос
SELECT name, address FROM companies WHERE name IN ("АО Рога и Копыта", "ТОО Добро пожаловать")
Очевидно, последний запрос можно сформулировать и с помощью операций "=" и "OR", но во многих случаях использование операции IN более наглядно и компактно.
Если же множество значений формируется динамически, в процессе выполнения запроса, то использование операции IN становится единственно возможным способом. Например, нам надо выполнить запрос "найти названия и адреса всех фирм, поставляющих джинсы". Этот запрос выполняется одним SQL-оператором:
SELECT name, address FROM companies WHERE company_id IN (SELECT company FROM items WHERE name = "джинсы")
В запросах подобного рода во внутренний оператор SELECT можно добавить слово UNIQUE - это позволит повысить скорость обработки запроса:
SELECT name, address FROM companies WHERE company_id IN (SELECT UNIQUE company FROM items WHERE name = "джинсы")
Если же требуется найти все фирмы, которые еще не поставляют нам кеды, то такой запрос получается небольшой модификацией предыдущего - заменой "джинсы" на "кеды" и добавлении операции NOT:
SELECT name, address FROM companies WHERE company_id NOT IN (SELECT company FROM items WHERE name = "кеды")
Для удаления из базы информации о всех фирмах, которые в настоящий момент ничего не поставляют, надо выполнить запрос:
DELETE FROM companies WHERE company_id NOT IN (SELECT company FROM items).
А так как у нас есть еще таблица persons с информацией о работниках фирм, то для сохранения логической целостности базы данных, надо провести еще и соответсвующие удаления из этой таблицы - вместе с информацией о фирме надо удалять и информацию о ее работниках и, более того, эти два удаления надо объединить в транзакцию. Поэтому, правильная последовательность действий по удалению из базы информации о фирмах, которые ничего не производят и не поставляют, будет выглядеть так:
BEGIN WORK DELETE FROM companies WHERE company_id NOT IN (SELECT company FROM items) DELETE FROM persons WHERE company NOT IN (SELECT company_id FROM companies) COMMIT WORK
Если известно, что оператор SELECT возвращает одну запись, то можно вместо слова IN использовать проверку на равенство. Например, если мы хотим получить список самых дорогих товаров, а именно их названия и цену (цена будет для всех одна - максимальная), то надо выплнить запрос:
SELECT name, price FROM items WHERE price = (SELECT MAX(price) FROM items)
Проверка на существование выборки
С помощью логической операции EXISTS можно проверить, возвращает ли тот или иной SELECT-оператор какие-то значения. Соответственно, можно в условии определять только те записи, для которых существует (или не существует) какая-то информация. Формат логической операции EXISTS:
EXISTS (<оператор SELECT>)
Например, приведенный выше запрос на поиск фирм, который ничего не поставляют, можно сформулировать с помощью операции EXISTS:
SELECT name, address FROM companies WHERE NOT EXISTS (SELECT company FROM items WHERE items.company=companies.company_id)
Какие поля возвращает оператор SELECT внутри логической операции EXISTS неважно. Неважно так же и количество найденных рядов. Важен только тот факт, был ли найден хотя бы один ряд, удовлетворяющий данному оператору SELECT.
Сравнивая операцию EXISTS с операцией IN, можно заметить. что одни и те же запросы можно выразить с помощью разных средств (а именно, EXISTS или IN). Какое из средств выбрать, должно определяться логикой задачи и эффективностью исполнения. Последнее, в свою очередь, зависит от реализации и может принципиально различаться для SQL-серверов разных фирм.
Условия "Существует" и "Для всех"
Всем, кто когда-то более или менее серьезно, занимался математикой, известны кванторы "Существует" и "Для всех". Аналогичные операции введены и в SQL. Эти операции должны использоваться после операции сравнения (больше, меньше, равно и т.д.), а в качестве правого операнда должен задаваться оператор SELECT:
<выражение> <операция сравнения> ALL (<оператор SELECT>) <выражение> <операция сравнения> ANY (<оператор SELECT>)
Соответсвенно, операция ALL возвращает значение "истина", если операция сравнения истинна для каждого значения, возвращаемого оператором SELECT, а операция ANY - хотя бы для одного. Если оператор SELECT не вернул ни одного знчения, то операция ALL возвращает истину, а ANY - ложь. Вместо ключевого слова ANY можно использовать слоово SOME.
Например, если мы хотим определить фирму-производителя самых дешевых кед, то запрос с использованием операции ALL будет выглядеть следующим образом:
SELECT company_id, name FROM companies WHERE EXISTS (SELECT company FROM items WHERE companies.company_id = items.company AND items.name = "кеды" AND items.price <= ALL (SELECT price FROM items WHERE name = "кеды") )
Тот же самый запрос мог быть сформулирован и с помощью агрегатной функции MIN:
SELECT company_id, name FROM companies WHERE EXISTS (SELECT company FROM items WHERE companies.company_id = items.company AND items.name = "кеды" AND items.price = (SELECT MIN(price) FROM items WHERE name = "кеды") )
- 4.5. Упражнения 67
- Глава 6. Устройство Informix Dynamic Server 165
- Глава 7. Эксплуатация информационных систем 177
- Глава 1 Обзор основных архитектур баз данных
- 1.1. Архитектура на основе разделяемых файлов
- 1.2. Архитектура “Хост-терминал”
- 1.3. Архитектура “Клиент-Сервер”
- 1.4. Архитектура с использованием сервера приложений (трехзвенная архитектура)
- 1.5. Упражнения
- Глава 2 Модели данных
- 2.1. Уровни восприятия данных
- 2.2. Иерархическая модель данных
- 2.3. Сетевая модель данных
- 2.4. Реляционная модель данных
- 2.5. Объектно-реляционная модель данных
- Глава 3 Реализация информационных систем на основе продуктов Informix Software
- 3.1. Обзор продуктов Informix
- 3.2. Варианты построения систем
- Internet/Intranet-конфигурация
- 3.3. Выбор оптимальной конфигурации
- Глава 4 Математические основы реляционных субд
- 4.1. Основные понятия
- 4.2. Ключи
- 4.3. Основные операции над таблицами и их интерпретация
- 4.4. Нормализация
- 4.5. Упражнения
- Глава 5 Язык sql
- 5.1. Типы данных, доступные в sql
- 5.3. Основные sql-операторы для доступа и модификации данных
- 5.4. Управление транзакциями
- 5.5. Продвинутые варианты оператора поиска
- 5.5.1. Поиск по нескольким таблицам
- 5.5.2. Устранение повторения данных в операторе select
- 5.5.3. Вычисления внутри оператора select
- 5.5.4. Логические выражения в условии sql-операторов
- 5.5.5. Слияние двух выборок
- 5.5.6. Сортировка выборки
- 5.5.7. Вставка в таблицу нескольких строк одновременно
- 5.6. Использование sql в языках программирования
- 5.7. Программирование сервера базы данных
- 5.7.1. Динамический sql
- 5.7.3. Хранимые процедуры
- 5.7.4. Триггеры
- 5.8. Ограничители (задание целостности на уровне схемы)
- 5.9. Разграничение в sql прав пользователей
- 5.9.1. Права доступа
- 5.9.2. Права на уровне базы данных
- 5.9.3. Права на таблицы
- 5.9.4. Права на хранимые процедуры
- 5.9.5. Кто и как следит за соблюдением прав
- 5.9.6. Механизм ролей
- 5.9.7. Псевдотаблицы (view)
- 5.9.7. Синонимы
- 5.10. Управление одновременным доступом к данным
- 5.10.1. Что бывает, когда несколько человек одновременно пытаются обновить одни и теже данные
- 5.10.2. Открытие базы данных только для себя
- 5.10.3. Блокирование таблицы
- 5.10.4. Механизм блокирования записей и уровни изоляции
- 5.10.5. Управление ожиданием снятия блокировок
- 5.10.6. Тупиковые ситуации
- 5.11. Повышение скорости обработки запросов.
- 5.11.1. Индексы
- 5.11.2. Буферизация журнала транзакций
- 5.11.3. Блокировка на уровне записей и страниц
- 5.11.4. Эффективное построение запросов
- 5.11.5. Сортировка и поиск по коротким полям. Классификаторы
- 5.12. Объектное расширение sql в Informix ds/Universal Data Option
- 5.12.1. Зачем нужна поддержка объектов в серверах бд?
- 5.12.3. Внедрение объектно-ориентированной технологии
- 5.12.4. Реализация объектного подхода в Informix
- Informix ds/Universal Data Option - объектно-реляционная субд
- 5.12.5. Итак…
- Глава 6. Устройство Informix Dynamic Server
- 6.1. Внутренняя архитектура dsa
- 6.2. Механизм хранения данных
- 6.3. Инсталляция продукта
- 6.4. Запуск и останов сервера
- 6.5. Работа с русским языком
- Глава 7. Эксплуатация информационных систем
- Администрирование серверов баз данных
- 7.2. Обеспечение сохранности данных.
- 7.2.1. Технологии постоянного дублирования
- 7.2.2. Архивация
- 7.2.3. Так как же обеспечить сохранность данных?
- 7.3. Архивирование и восстановление данных
- 7.3.1. Что нужно архивировать
- 7.3.2. Утилиты архивации и восстановления
- 7.3.3. Создание архивов утилитой ontape
- 7.3.4. Восстановление из архивов утилитой ontape
- 7.3.5. Как узнать “когда”?
- 7.3.6. Практические советы
- 7.4. Средства контроля за доступом
- 7.4.1 Как работает аудитинг?
- 7.4.2. Конфигурирование списков протоколируемых событий
- 7.4.3. Задание файлов, запуск и остановка механизма аудитинга
- Анализ протокола
- 7.4.5. Практические советы или Что делать, если вы хотите…
- 7.5. Реагирование на чрезвычайные ситуации
- 7.6. Мониторинг текущего состояния сервера базы данных
- 7.6.1. Кто работает с сервером базы данных
- 7.6.2. Сколько памяти использует сервер бд
- 7.6.3. Сколько свободного места имеется у сервера бд
- 7.7. Достижение требуемой производительности
- 7.7.1. Как узнать, что ждет некоторый запрос
- 7.7.2. Как выяснять причины падения производительности
- 2. Общие принципы предлагаемой технологии
- 3. Как портировать приложение