Предикаты
Предикат — это выражение, результатом которого являются значения TRUE, FALSE или UNKNOWN. Предикаты используются в условиях поиска предложений WHERE и HAVING, в условиях соединения предложений FROM и других конструкциях, где требуется логическое значение.
SQL Server предоставляет следующие предикаты:
См. также
- BETWEEN (Transact-SQL)
- EXISTS (Transact-SQL)
- IN (Transact-SQL)
- LIKE (Transact-SQL)
- Условие поиска (Transact-SQL)
Обратная связь
Были ли сведения на этой странице полезными?
Обратная связь
Отправить и просмотреть отзыв по
Предикаты поиска
Перед тем, как SQL Server приступит к поиску по индексу, он должен определить, являются ли ключи индекса подходящими для оценки предиката запроса.
Индексы по одному столбцу
С индексами по одному столбцу всё довольно просто. SQL Server может их использовать для самых простых сравнений, например, равенства и неравенства (больше чем, меньше чем, и т.д.). Более сложные выражения, такие как функции по столбцу и предикаты «LIKE» с символами подстановки, будут в таких случаях создавать трудности для использования поиска по индексу.
Например, предположим, что мы имеем индекс по одному столбцу, созданный по полю «a». Этот индекс может использоваться для поиска при следующих предикатах:
a = 3.14 a > 100 a between 0 and 99 a like 'abc%' a in (2, 3, 5, 7)
Однако, поиск по индексу не будет задействован если использовать вот такие предикаты:
ABS(a) = 1 a + 1 = 9 a like '%abc'
Индексы по нескольким столбцам
С индексами по нескольким столбцам дело обстоит сложнее. Для таких индексов важен порядок ключей. Этим определяется порядок сортировки индекса, и от порядка ключей зависит набор предикатов поиска, которые SQL Server сможет использовать для этого индекса.
Для того, чтобы проще понять важность порядка ключей, представьте себе телефонную книгу. Для телефонной книги походит индекс с ключами: «фамилия» и «имя». Содержание телефонной книги отсортировано по фамилии, что упрощает поиск кого-нибудь, если мы знаем его фамилию. Однако, если мы знаем только имя, очень трудно получить список людей с необходимым нам именем. В таком случае, нам бы лучше подошла другая телефонная книга, в которой абоненты отсортированы по имени.
Точно также обстоит дело, если мы имеем индекс по двум столбцам, т.е. мы сможем использовать индекс только для предиката по второму столбцу, если указан предикат равенства для первого столбца. Даже если мы не сможем использовать индекс для удовлетворения условия предиката второго столбца, мы сможем использовать его для первого столбца. В этом случае, вводится остаточный предикат для предиката второго столбца, который будет тем же самым предикатом, который используется для просмотра.
Например, предположим, что у нас есть индекс по двум столбцам «a» и «b». Мы можем его использовать для поиска по любому из предикатов, которые применимы для индексов по одному столбцу. Кроме того, можно использовать это индекс и для поиска со следующими дополнительными предикатами:
a = 3.14 and b = 'pi' a = 'xyzzy' and b
Для следующих ниже примеров, мы можем использовать индекс для удовлетворения условий предиката для столбца "a", но не для столбца "b". В этих случаях потребуется остаточный предикат:
a > 100 and b > 100 a like 'abc%' and b = 2
И, наконец, невозможно использовать индекс для поиска со следующим ниже набором предикатов, поскольку поиск невозможен даже по столбцу "a". В таких случаях, оптимизатор вынужден использовать другой индекс (например, такой индекс, у которого столбец "b" указан первым), или он будет использовать просмотр с остаточным предикатом.
b = 0 a + 1 = 9 and b between 1 and 9 a like '%abc' and b in (1, 3, 5)
Добавим в пример немного конкретики.
Рассмотрим следующую схему:
create table person (id int, last_name varchar(30), first_name varchar(30)) create unique clustered index person_id on person (id) create index person_name on person (last_name, first_name)
Ниже представлены три запроса с соответствующими им текстовыми планами исполнения. Первый запрос осуществляет поиск по обоим столбцам индекса person_name. Второй запрос ищет только по первому столбцу и использует остаточный предикат, для оценки first_name. Третий запрос не может использовать поиск и использует просмотр с остаточным предикатом.
select id from person where last_name = 'Doe' and first_name = 'John' |--Index Seek(OBJECT:([person].[person_name]), SEEK:([person].[last_name]='Doe' AND [person].[first_name]='John')) select id from person where last_name > 'Doe' and first_name = 'John' |--Index Seek(OBJECT:([person].[person_name]), SEEK:([person].[last_name] > 'Doe'), WHERE:([person].[first_name]='John')) select id from person where last_name like '%oe' and first_name = 'John' |--Index Scan(OBJECT:([person].[person_name]), WHERE:([person].[first_name]='John' AND [person].[last_name] like '%oe'))
Внимание: Если Вы пробуете воспроизвести эти планы для этих и некоторых следующих примеров, учтите, что я использовал подсказки индексов (которые не указаны), позволяющие гарантировать получение необходимого плана запроса, поскольку я хотел проиллюстрировать эти примеры без необходимости вставки данных в таблицу.
Дополнение о ключах индекса
Очень часто ключи индекса являются набором столбцов, которые были указаны в инструкции по созданию этого индекса. Однако, когда создается некластеризованный уникальный индекс для таблицы с кластеризованным индексом, в ключ некластеризованного индекса добавляется ключ кластеризованного индекса, если он не является частью ключей некластеризованного индекса. Поиск по этим неявным ключам осуществляется точно так же, как если бы они были определены явно.
Например, рассмотрим такую схему:
create table T_heap (a int, b int, c int, d int, e int, f int) create index T_heap_a on T_heap (a) create index T_heap_bc on T_heap (b, c) create index T_heap_d on T_heap (d) include (e) create unique index T_heap_f on T_heap (f) create table T_clu (a int, b int, c int, d int, e int, f int) create unique clustered index T_clu_a on T_clu (a) create index T_clu_b on T_clu (b) create index T_clu_ac on T_clu (a, c) create index T_clu_d on T_clu (d) include (e) create unique index T_clu_f on T_clu (f)
Столбцы ключей и покрываемые столбцы для каждого из индексов:
Индекс
Столбцы ключа
Покрываемые столбцы
Операторы SQL AND и OR
Операторы SQL AND и SQL OR — предикаты языка SQL, служащие для создания логических выражений. В SQL предикатами называются операторы, возвращающие значения TRUE или FALSE. Предикат SQL AND — эквивалент логического умножения (конъюнкции), предикат SQL OR — эквивалент логического сложения (дизъюнкции).
Таблица истинности для предикатов следующая:
first_expression | last_expression | AND | OR |
TRUE | TRUE | TRUE | TRUE |
TRUE | FALSE | FALSE | TRUE |
FALSE | TRUE | FALSE | TRUE |
FALSE | FALSE | FALSE | FALSE |
Это значит, что, для выполнения условия предиката SQL AND должны быть выполнены оба условия. Для выполнения предиката SQL OR должно быть выполнено хотя бы одно условие.
Предикат SQL AND имеет следующий синтаксис:
boolean_expression AND boolean_expression
Предикат SQL OR имеет следующий синтаксис:
boolean_expression OR boolean_expression
Примеры оператора SQL AND & OR. Имеется следующая таблица Planets :
ID | PlanetName | Radius | SunSeason | OpeningYear | HavingRings | Opener |
1 | Mars | 3396 | 687 | 1659 | No | Christiaan Huygens |
2 | Saturn | 60268 | 10759.22 | — | Yes | — |
3 | Neptune | 24764 | 60190 | 1846 | Yes | John Couch Adams |
4 | Mercury | 2439 | 115.88 | 1631 | No | Nicolaus Copernicus |
5 | Venus | 6051 | 243 | 1610 | No | Galileo Galilei |
Пример 1. Используя операторы SQL AND и SQL OR вывести записи планет, у которых радиус планеты меньше 10000 и открытых (OpeningYear) после 1620:
SELECT * FROM Planets WHERE Radius < 10000 AND OpeningYear >1620
ID | PlanetName | Radius | SunSeason | OpeningYear | HavingRings | Opener |
1 | Mars | 3396 | 687 | 1659 | No | Christiaan Huygens |
4 | Mercury | 2439 | 115.88 | 1631 | No | Nicolaus Copernicus |
Пример 2. Используя операторы SQL AND и SQL OR вывести записи планет, названия которых начинаются с буквы «N» или заканчиваются на букву «s» и не имеющие колец:
SELECT * FROM Planets WHERE (PlanetName LIKE 'N%' OR PlanetName LIKE '%s') AND HavingRings = 'No'
ID | PlanetName | Radius | SunSeason | OpeningYear | HavingRings | Opener |
1 | Mars | 3396 | 687 | 1659 | No | Christiaan Huygens |
5 | Venus | 6051 | 243 | 1610 | No | Galileo Galilei |
В этом примере используются как предикат SQL AND так и SQL OR. Конечно же, в запросах их можно использовать сколько угодно раз (так же как и скобки, которые их ограничивают), для задания более точного условия выборки.
Предикаты I стр. 1
Предикаты представляют собой выражения, принимающие истинностное значение. Они могут представлять собой как одно выражение, так и любую комбинацию из неограниченного количества выражений, построенную с помощью булевых операторов AND , OR или NOT . Кроме того, в этих комбинациях может использоваться SQL-оператор IS , а также круглые скобки для конкретизации порядка выполнения операций.
Предикат в языке Язык структурированных запросов) — универсальный компьютерный язык, применяемый для создания, модификации и управления данными в реляционных базах данных. SQL может принимать одно из трех значений TRUE (истина), FALSE (ложь) или UNKNOWN (неизвестно). Исключение составляют следующие предикаты: IS NULL (отсутствие значения), EXISTS (существование), UNIQUE (уникальность) и MATCH (совпадение), которые не могут принимать значение UNKNOWN .
Правила комбинирования всех трех истинностных значений легче запомнить, обозначив TRUE как 1, FALSE как 0 и UNKNOWN как 1/2 (где-то между истинным и ложным значениями) [2].
AND с двумя истинностными значениями дает минимум этих значений. Например, TRUE AND UNKNOWN будет равно UNKNOWN .
OR с двумя истинностными значениями дает максимум этих значений. Например, FALSE OR UNKNOWN будет равно UNKNOWN .
Отрицание истинностного значения равно 1 минус данное истинностное значение. Например, NOT UNKNOWN будет равно UNKNOWN .