1с запрос где истина
Эффективные условия запросов
Область применения: управляемое приложение, мобильное приложение, обычное приложение.
1. Условия запросов должны быть написаны оптимально с точки зрения производительности, чтобы исключить существенное увеличение длительности выполнения запросов при увеличении объема данных в таблицах.
Поля основного условия в секциях ГДЕ, ПО и виртуальных таблицах должны быть проиндексированы. Основное условие может быть уточнено дополнительным условием, но объединять их следует только по И.
Важно понимать структуру индексов, которые получаются при индексировании полей и учитывать их при построении основного условия (см. Индексы таблиц базы данных, Несоответствие индексов и условий запроса). Например, при индексировании разных полей одного объекта метаданных создаются разные индексы, а не один в который помещаются все проиндексированные поля и использоваться основным условием будет только один из них.
Основное условие – это то, что позволяет ограничить объем выборки больше других условий и его составляющие объединены по И.
Дополнительное условие – это то, что объединено с основным условием по И и его составляющие могут быть любой сложности (НЕ, <>, +, -, /, *, функции и т.п.).
Основное условие должно содержать только такие операции, которые позволяют выполнять поиск по индексу:
- для первого и всех используемых полей индекса, кроме последнего, только = и И;
- для последнего или единственного используемого поля индекса допустимо использовать =, >, <, >=, <=, ПОДОБНО, МЕЖДУ, В, ИЛИ (приводимое к В);
- нельзя использовать арифметические операции, функции, отрицания и неравенства.
Для условий в ГДЕ или в виртуальной таблице следует индексировать поля в основной таблице, из которой выполняется выборка.
Для условий в ПО ЛЕВОГО соединения следует индексировать поля в правой таблице.
Для условий в ПО ВНУТРЕННЕГО соединения следует индексировать поля в таблице с большим количеством записей.
Основное условие желательно строить таким образом, чтобы оно использовало индексы, которые автоматически создает платформа.
1.1. Описанные выше требования допустимо не соблюдать, если в таблицах, из которых выполняется выборка, или с которыми выполняется соединение, всегда будет мало данных (менее 1000 записей) или запросы с такими условиями выполняются очень редко.
1.2. Если записей в таблице много и выполнить указанные выше требования невозможно, то можно попробовать:
- преобразовать условия (см. п. 3, п. 4);
- добавить в таблицу заранее вычисляемые индексированные поля, которые заполняются при записи в нее и используются вместо сложного условия;
- если указанные выше рекомендации не помогли, то следует пересмотреть архитектуру решения так, чтобы можно было выполнить эти условия.
2.1. В основном условии оператор ИЛИ можно использовать только для последнего из используемых или единственного поля индекса, когда оператор ИЛИ можно заменить на оператор В.
ГДЕ
Таблица.Поле = &Значение1
ИЛИ Таблица.Поле = &Значение2
т.к. можно переписать при помощи оператора В (специально переписывать не нужно, можно оставить, как есть):
ГДЕ
Таблица.Поле В (&Значения)
ГДЕ
Таблица.Поле1 = &Значение1
ИЛИ Таблица.Поле2 = &Значение2
нельзя переписать при помощи "В", но можно переписать при помощи "ОБЪЕДИНИТЬ ВСЕ" (каждое поле Поле1 и Поле2 должны быть проиндексированы):
ГДЕ
Таблица.Поле1 = &Значение1
ГДЕ
Таблица.Поле2 = &Значение1
Примечание: заменить ИЛИ на ОБЪЕДИНИТЬ ВСЕ можно не всегда, убедитесь, что результат будет действительно тем же, что и при ИЛИ, перед тем, как применять.
2.2. В дополнительном условии оператор ИЛИ можно использовать без ограничений.
ГДЕ
Таблица.Поле1 = &Значение1 // Основное условие (использует индекс)
И // Дополнительное условие (можно использовать ИЛИ)
(Таблица.Поле2 = &Значение2 ИЛИ Таблица.Поле3 = &Значение3)
ГДЕ
(Таблица.Поле1 = &Значение1 ИЛИ Таблица.Поле1 = &Значение2)
И
(Таблица.Поле2 = &Значение3 ИЛИ Таблица.Поле2 = &Значение4)
т.к. можно переписать при помощи В (специально переписывать не нужно, можно оставить, как есть):
ГДЕ
Таблица.Поле1 В (&Значения1) // Основное условие
И Таблица.Поле2 В (&Значения2) // Дополнительное условие (или наоборот)
3. Оператор ПОДОБНО
В основном условии для последнего из используемых или единственного поля индекса можно использовать оператор ПОДОБНО. Функции работы со строками, в некоторых случаях, можно привести к оператору ПОДОБНО и использовать его в основном условии.
ГДЕ
ПОДСТРОКА(Таблица.Поле, 1, 6) = "строка"
ГДЕ
Таблица.Поле ПОДОБНО "строка%"
ГДЕ
ПОДСТРОКА(Таблица.Поле, 3, 6) = "строка"
ГДЕ
Таблица.Поле ПОДОБНО "__строка%" // Литерал не должен начинаться с символов "_" или "%"
Добавить новое вычисляемое при записи в таблицу поле, которое будет содержать фрагмент ПОДСТРОКА(Таблица.Поле, 3, 6). Проиндексировать это поле и искать по следующему условию:
ГДЕ
Таблица.ВычисляемоеПоле ПОДОБНО "строка%"
4. Оператор МЕЖДУ
В основном условии для последнего из используемых или единственного поля индекса можно использовать оператор МЕЖДУ. Функции работы с датой, в некоторых случаях, можно привести к оператору МЕЖДУ и использовать его в основном условии.
ГДЕ
МЕСЯЦ(Таблица.Поле) = 1
ГДЕ
Таблица.Поле МЕЖДУ &ДатаНачалаМесяца И &ДатаКонцаМесяца
Например, ДатаНачалаМесяца=01.01.2016, ДатаКонцаМесяца=31.01.2016 23:59:59
5. Выражение ВЫБОР
Выражение ВЫБОР можно использовать только в дополнительных условиях.
ГДЕ
Таблица.Поле1 = &Значение1 // Основное условие (использует индекс)
И // Дополнительное условие (можно использовать ВЫБОР)
ВЫБОР
КОГДА Таблица.Поле2 = &Значение2
ТОГДА Таблица.Поле3 = &Значение3
ИНАЧЕ Таблица.Поле4 = &Значение4
КОНЕЦ
ГДЕ
ВЫБОР // Основное условие (поиск по индексу использоваться не будет)
КОГДА Таблица.Поле2 = &Значение2
ТОГДА Таблица.Поле3 = &Значение3
ИНАЧЕ Таблица.Поле4 = &Значение4
КОНЕЦ
6. Арифметические операции
Арифметические операции над полями можно выполнять только в дополнительных условиях.
ГДЕ
Таблица.Поле1 = &Значение1 // Основное условие (использует индекс)
И // Дополнительное условие (можно выполнять арифметические операции)
Таблица.Поле2 - 1 > 0
ГДЕ
Таблица.Поле1 - 1 > 0 // Основное условие (поиск по индексу невозможен)
7. Если в конфигурации описано несколько ролей с разным ограничением доступа на уровне записей (RLS), то не следует назначать одному пользователю более одной такой роли. Если один пользователь будет включен, например, в две роли с RLS - бухгалтер и кадровик, то при выполнении всех его запросов к их условиям будут добавляться условия обоих RLS с использованием логического ИЛИ. Таким образом, даже если в исходном запросе нет условия ИЛИ, оно появится там после добавления условий RLS. Такой запрос так же может выполняться неоптимально - медленно и с избыточными блокировками.
Рассмотрим назначение и использование условного оператора ПОДОБНО(eng. LIKE) в языке запроса 1С в примерах.
Предназначение
Места использования
Описание синтаксиса оператора ПОДОБНО
Параметр оператора должен быть строкой: может задаться константой, либо передан как параметр запроса.
Литералы(маски), указанные ниже, допускается использовать совместно и по отдельности.
Точное указание строки
ВЫБРАТЬ первые 10
Ключи.Наименование
ИЗ
Справочник.Ключи КАК Ключи
ГДЕ
Ключи.Наименование ПОДОБНО "1"//Равносильно Ключи.Наименование ="1"
Результат:
ВЫБРАТЬ первые 10
Ключи.Наименование
ИЗ
Справочник.Ключи КАК Ключи
ГДЕ
Ключи.Наименование ПОДОБНО "%"
Результат: любые 10 наименований
_ (подчеркивание): литерал, соответствующий одному любому символу
Пример №1:
ВЫБРАТЬ первые 10
Ключи.Наименование
ИЗ
Справочник.Ключи КАК Ключи
ГДЕ
Ключи.Наименование ПОДОБНО "_"
ВЫБРАТЬ первые 10
Ключи.Наименование
ИЗ
Справочник.Ключи КАК Ключи
ГДЕ
Ключи.Наименование ПОДОБНО "_1%"
Результат:
[] (в квадратных скобках один или несколько символов)
Пример
ВЫБРАТЬ первые 10
Ключи.Наименование
ИЗ
Справочник.Ключи КАК Ключи
ГДЕ
Ключи.Наименование ПОДОБНО "[лз]%"
Пример: начинающиеся на 5,6,7
ВЫБРАТЬ первые 10
Ключи.Наименование
ИЗ
Справочник.Ключи КАК Ключи
ГДЕ
Ключи.Наименование ПОДОБНО "6%"
Результат:
[^] (в квадратных скобках значок исключения ^, за которым следует один или несколько символов)
Равносильно любому символу (_) кроме указанных ([])
Пример
ВЫБРАТЬ первые 10
Ключи.Наименование
ИЗ
Справочник.Ключи КАК Ключи
ГДЕ
Ключи.Наименование ПОДОБНО "8.[^012]%"//не включаем 8.0,8.1,8.2
Пример:
Результат:
Применимость в платформах
Неверные параметры ПОДОБНО <<?>>
Обратите внимание на текст ошибки, где выводится вопрос:
Вести бизнес без рекламы все равно, что подмигивать девушкам в полной темноте
— Стюарт Хендерсон Бритт
В качестве источника в запросах можно указать несколько разных таблиц. Если не указать никакие условия для связи таблиц, то будет получено декартово произведение (все возможные комбинации строк) или как еще называют перекрестное соединение.
Например, в базе есть 2 таблицы: ЛеваяТаблица и ПраваяТаблица. Состав таблиц следующий:
В результате выполнения следующего запроса:
Будет получен такой результат:
Каждая запись из левой таблицы была связана с каждой записью из правой таблицы.
Виды соединений в запросе
Соединения нужны для того, чтобы соединить строки разных таблиц по какому-либо условию. Условия указываются после ключевого слова ПО. Может быть несколько условий при одном соединении.
Язык запросов 1С поддерживает следующие виды соединений:
- Внутреннее соединение
- Левое внешнее соединение
- Правое внешнее соединение
- Полное внешнее соединение
В запросах позволяется не указывать слова внутреннее и внешнее.
Внутреннее соединение
В результате внутреннего соединения таблиц в выборку попадут только те записи, которые удовлетворяют условию соединения:
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПраваяТаблица КАК ПраваяТаблица
В результат запроса не попала четвертая запись из левой таблицы, потому что для нее не нашлось записи в правой таблице, которая бы удовлетворяла условию ЛеваяТаблица.Код = ПраваяТаблица.Код.
Левое соединение
В результате левого соединения таблиц в выборку попадут все записи из левой таблицы, и только те записи из правой таблицы, которые удовлетворяют условию соединения:
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПраваяТаблица КАК ПраваяТаблица
В четвертой строке в полях ПравоеНаименование и ПравыйКод будет NULL.
Правое соединение
Это то же самое, что и левое соединение, только таблицы меняются местами. В результате правого соединения таблиц в выборку попадут все записи из правой таблицы, и только те записи из левой таблицы, которые удовлетворяют условию соединения. Очень редко используется на практике:
ПРАВОЕ СОЕДИНЕНИЕ Справочник.ПраваяТаблица КАК ПраваяТаблица
В четвертой строке в полях ЛевоеНаименование и ЛевыйКод будет NULL.
Полное соединение
ПОЛНОЕ СОЕДИНЕНИЕ Справочник.ЛеваяТаблица КАК ЛеваяТаблица
В четвертой строке в полях ЛевоеНаименование и ЛевыйКод будет NULL. В пятой строке в полях ПравоеНаименование и ПравыйКод будет NULL.
Два левых соединения в запросе
Допустим, что есть еще одна таблица со следующим содержимым:
И нужно связать и ее и правую таблицу с левой. Для этого можно использовать два левых соединения:
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПраваяТаблица КАК ПраваяТаблица ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ЕщеТаблица КАК ЕщеТаблица
Точно также можно связать и три таблицы, и четыре и т.д. То же самое относится и к внутреннему, правому и полному соединению.
Левое соединение с условием
Если при левом соединении наложить условие на поле правой таблицы, то соединение будет автоматически преобразовано во внутреннее соединение:
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПраваяТаблица КАК ПраваяТаблица
Чтобы получить правильный результат нужно условие перенести из предложения ГДЕ в условие соединения:
Войдите как ученик, чтобы получить доступ к материалам школы
Язык запросов 1С 8.3 для начинающих программистов: условный оператор
Автор уроков и преподаватель школы: Владимир Милькин
Условный оператор в запросе
Давайте напишем запрос, который получает названия и калорийность еды:
А теперь добавим в результат запроса колонку, в которую будем выводить жирность еды по следующим правилам:
- если калорийность меньше 100, то жирность низкая;
- если калорийность от 100 до 200, то жирность нормальная;
- если калорийность больше 200, то жирность высокая.
Как этого можно добиться, ведь в таблице Справочник.Еда нет колонки Жирность?
Оказывается, эту колонку мы можем добавить сами, используя условный оператор внутри запроса:
Давайте внимательнее присмотримся к тексту запроса:
В секции ВЫБРАТЬ идёт перечисление полей выборки: Наименование, Калорийность, а затем вместо третьего поля идёт конструкция условного оператора, результат которого и попадает в третью колонку.
Условия оператора обрабатываются последовательно . Если одно из них оказалось верным, то в качестве результата возвращается соответствующее значение. Если же ни одно из условий не выполнилось, то возвращается значение из секции ИНАЧЕ. Если же ни одно из условий не выполнилось, и в операторе отсутствует секция ИНАЧЕ, то возвращается значение NULL (о нём мы поговорим в одном из следующих уроков).
Поэтому новый запрос вернёт такую таблицу:
Отступление
Обратите внимание, что третья колонка в таблице, которую вернул запрос, называется Поле1. Это имя было сгенерировано системой автоматически, потому что третьей колонке не соответствует никакого реального поля в таблице Справочник.Еда, откуда можно было бы это имя получить.
Но в наших силах дать ей это имя. Для этого сразу после описания поля нужно написать ключевое слово КАК, а после этого через пробел указать само имя. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Такое имя будет называться псевдонимом поля .
Псевдонимы можно присваивать любым полям, в том числе тем, у которых уже есть имя. Давайте сделаем псевдоним Еда для поля Наименование:
Но вернёмся к условному оператору в запросах.
Более сложные логические выражения в условиях оператора
В логических условиях оператора выбора можно использовать и более сложные выражения.
Пример использования логического оператора ПОДОБНО:
Пример использования функции ПОДСТРОКА:
Более сложные результаты условного оператора
Конечно, результатом условного оператора может быть не только константная строка, но и любое другое выражение, допустимое в запросе.
Читайте также: