К статье
Практический материал

Разработка и Конфигурация · 11 мин

Оператор ГДЕ в запросах 1С 8: полное руководство с примерами

Как работает оператор ГДЕ в языке запросов 1С 8: синтаксис, логические условия, сравнение с ИМЕЮЩИЕ, типичные ошибки и готовые примеры кода.

Оператор ГДЕ (WHERE) — основной инструмент фильтрации записей в языке запросов 1С 8. Он отбирает из источника данных только те строки, которые удовлетворяют заданному условию, ещё до группировки, соединения с другими таблицами и вывода результата. Правильное использование ГДЕ напрямую влияет на скорость выполнения запроса: чем раньше отсекаются лишние записи, тем меньше данных обрабатывает платформа.

В запросах 1С оператор ГДЕ работает почти так же, как WHERE в классическом SQL, но имеет особенности: поддержку параметров через символ «&», специальные конструкции вроде В ИЕРАРХИИ, ССЫЛКА и ВЫРАЗИТЬ, а также строгую типизацию сравниваемых значений. Ошибка в типе операнда — самая частая причина «пустого» результата запроса, который внешне выглядит корректным.

Материал рассчитан на разработчиков и внедренцев, которые пишут запросы в конфигураторе, консоли запросов или программно из модулей. Разобраны синтаксис, логические операторы, работа с виртуальными таблицами, отличие от ИМЕЮЩИЕ и типичные ошибки с примерами кода.

Синтаксис и место оператора ГДЕ в структуре запроса

Конструкция ГДЕ размещается после предложения ИЗ (и необязательных соединений СОЕДИНЕНИЕ) и до ГРУППИРОВКА ПО, ИМЕЮЩИЕ и УПОРЯДОЧИТЬ ПО. Общий порядок секций запроса фиксирован, нарушать его нельзя — конструктор запроса и компилятор выдадут ошибку.

ВЫБРАТЬ

Номенклатура.Ссылка КАК Товар,

Номенклатура.Цена КАК Цена

ИЗ

Справочник.Номенклатура КАК Номенклатура

ГДЕ

Номенклатура.Цена > 1000

И НЕ Номенклатура.ПометкаУдаления

Условие в ГДЕ — это логическое выражение, которое должно возвращать Истина или Ложь для каждой строки. Внутри выражения допустимы операции сравнения (=, <>, >, <, >=, <=), логические связки И, ИЛИ, НЕ, а также специальные предикаты В, МЕЖДУ, ПОДОБНО, ЕСТЬ NULL. Приоритет операций стандартный: сначала НЕ, затем сравнения, затем И, в конце ИЛИ. Для управления порядком используйте скобки — это убирает неоднозначность и облегчает чтение.

Обратите внимание: в условии можно обращаться к полям через точку (разыменование), но каждое такое обращение при больших объёмах данных может порождать неявные соединения. Если фильтр идёт по реквизиту ссылочного поля, часто выгоднее передать в параметр готовое значение, чем строить условие вида Товары.Номенклатура.Родитель = &Группа.

Логические условия, сравнения и предикаты

Базовые сравнения работают с числами, строками, датами, булевыми значениями и ссылками. Важно, чтобы типы операндов совпадали или были совместимы: сравнение строки с числом не вызовет ошибки, но вернёт Ложь для всех строк, и запрос молча отдаст пустой результат.

Предикат В проверяет вхождение значения в список или результат вложенного запроса. МЕЖДУ задаёт диапазон включительно по обеим границам. ПОДОБНО выполняет поиск по шаблону: символ «%» заменяет любую последовательность, «_» — один символ. ЕСТЬ NULL отбирает строки с незаполненным значением, что особенно актуально при левых соединениях.

ГДЕ

Продажи.Номенклатура В (&СписокТоваров)

И Продажи.Период МЕЖДУ &НачалоПериода И &КонецПериода

И Продажи.Контрагент.Наименование ПОДОБНО "%ООО%"

Отдельный случай — В ИЕРАРХИИ, который отбирает элементы справочника, входящие в указанную группу с учётом всех уровней вложенности. Это штатный способ фильтрации по папке номенклатуры или контрагентов без рекурсивных обходов в коде.

Параметры запроса и передача значений в условие

Параметры в тексте запроса обозначаются символом «&» и заполняются через метод УстановитьПараметр объекта Запрос до выполнения. Использование параметров вместо подстановки значений конкатенацией строк — обязательная практика: это защищает от ошибок типизации и делает текст запроса читаемым.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Реализация.Ссылка

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Реализация

|ГДЕ

| Реализация.Контрагент = &Контрагент

| И Реализация.Проведен";

Запрос.УстановитьПараметр("Контрагент", ВыбранныйКонтрагент);

В параметр можно передавать массив или список значений — тогда условие записывается через В (&Параметр). Это удобно для отбора по произвольному набору ссылок. Для дат помните о границах периода: дата без времени означает начало дня, поэтому конец периода обычно задают либо как конец дня, либо используют условие «меньше следующего дня».

Фильтрация в виртуальных таблицах регистров

При обращении к виртуальным таблицам регистров накопления и сведений (Остатки, Обороты, СрезПоследних) условия корректнее передавать в параметрах виртуальной таблицы, а не в секции ГДЕ. Параметры виртуальной таблицы указываются в круглых скобках после её имени и применяются на этапе выборки данных — это существенно быстрее, чем фильтровать уже полученный полный набор записей.

ВЫБРАТЬ

Остатки.Номенклатура,

Остатки.КоличествоОстаток

ИЗ

РегистрНакопления.ТоварыНаСкладах.Остатки(

&Период,

Склад = &Склад

И Номенклатура В (&СписокНоменклатуры)) КАК Остатки

Если то же условие вынести в ГДЕ основного запроса, виртуальная таблица сначала вычислит остатки по всем складам и всей номенклатуре, и лишь потом отбросит лишнее. На больших регистрах разница во времени выполнения измеряется порядками. Правило простое: всё, что можно отфильтровать параметрами виртуальной таблицы, фильтруется именно там.

Типичные ошибки
01
Условие по периоду и измерениям написано в ГДЕ вместо параметров виртуальной таблицы — запрос считывает лишние данные и работает медленно
02
Сравнение ссылки со строкой или числом — запрос не падает с ошибкой, а молча возвращает пустой результат
03
Использование ИЛИ без скобок вместе с И — из-за приоритета операций условие трактуется иначе, чем задумано
04
Подстановка значений в текст запроса конкатенацией вместо параметров — риск ошибок типизации и нечитаемый код

Отличие ГДЕ от ИМЕЮЩИЕ

ГДЕ фильтрует строки до группировки, а ИМЕЮЩИЕ (HAVING) — уже сгруппированные итоги. Если нужно отобрать исходные записи (например, конкретный склад), используется ГДЕ. Если нужно оставить только те группы, где сумма превышает порог, — ИМЕЮЩИЕ с агрегатной функцией.

ВЫБРАТЬ

Продажи.Номенклатура,

СУММА(Продажи.Количество) КАК Продано

ИЗ

РегистрНакопления.Продажи.Обороты(&Начало, &Конец, , ) КАК Продажи

СГРУППИРОВАТЬ ПО

Продажи.Номенклатура

ИМЕЮЩИЕ

СУММА(Продажи.Количество) > 100

Частая ошибка — попытка написать условие по агрегатной функции в ГДЕ. Компилятор запроса это отклонит: агрегаты вычисляются после группировки, а ГДЕ выполняется до неё. Обратная ситуация — фильтрация обычных полей в ИМЕЮЩИЕ — технически возможна, но менее эффективна: сначала будут сгруппированы все строки, и только потом лишние отброшены.

Сравнение вариантов

ГДЕ

Фильтрует строки источника до группировки. Подходит для отборов по полям, периодам, ссылкам. Не работает с агрегатными функциями

ИМЕЮЩИЕ

Фильтрует группы после вычисления агрегатов. Нужен для условий вида СУММА(...) &gt; N. Для обычных полей менее эффективен, чем ГДЕ

Параметры виртуальной таблицы

Применяются на этапе выборки из регистра. Самый быстрый вариант для условий по периоду, измерениям и реквизитам виртуальной таблицы

Проверка результата и отладка запроса

Отлаживать условие удобнее всего в консоли запросов: текст вставляется без изменений, параметры заполняются в отдельной таблице, результат виден сразу. Если запрос возвращает пустоту, хотя данные в базе есть, проверяйте условия по одному — закомментируйте все строки ГДЕ и добавляйте их обратно по одной, пока не найдётся «съедающее» данные условие.

Признаки типичных проблем: пустой результат при корректном синтаксисе почти всегда означает несовпадение типов или логики условий; неожиданно большой результат — потерянное условие или неверный приоритет И/ИЛИ без скобок; медленное выполнение — фильтрация в ГДЕ того, что должно быть в параметрах виртуальной таблицы.

Контрольные точки

Как проверить результат

Количество строк результата
Норма

Совпадает с выборкой тех же данных через список справочника или отчёт с тем же отбором

Тревожный признак

Результат пуст или содержит заметно больше/меньше строк, чем ожидалось

Типы сравниваемых значений
Норма

Ссылка сравнивается со ссылкой, дата с датой, число с числом

Тревожный признак

В параметр передано значение другого типа — условие молча не срабатывает

Скорость выполнения
Норма

Запрос по виртуальной таблице с параметрами отбора выполняется быстро даже на больших данных

Тревожный признак

Условия по измерениям вынесены в ГДЕ — заметные задержки

Полезный приём — временно вывести в поля запроса само проверяемое выражение или его части. Например, добавить поле Продажи.Период и визуально убедиться, что границы периода попадают в выборку. Для сложных условий со скобками помогает разбить выражение на простые составляющие и тестировать каждое отдельно.

Порядок действий при написании условия
  1. 1
    Определите, что фильтруется: строки источника (ГДЕ), итоги группировки (ИМЕЮЩИЕ) или выборка из регистра (параметры виртуальной таблицы)
  2. 2
    Запишите условие с параметрами через & и расставьте скобки при сочетании И и ИЛИ
  3. 3
    Проверьте типы: значения параметров должны соответствовать типам полей
  4. 4
    Выполните запрос в консоли запросов и сверьте количество строк с контрольной выборкой
  5. 5
    При пустом результате отключайте условия по одному, чтобы найти проблемное

Частые вопросы

Можно ли использовать ГДЕ без ИЗ?

Нет. Секция ГДЕ всегда относится к источнику данных, указанному в ИЗ. Даже в запросе вида «ВЫБРАТЬ &Параметр ГДЕ ИСТИНА» платформа потребует источник; на практике такие конструкции заменяют простым ВЫБРАТЬ без условий.

Как проверить поле на NULL в условии?

Через предикат ЕСТЬ NULL: ГДЕ Таблица.Поле ЕСТЬ NULL. Сравнение «= NULL» не работает — NULL не равен ничему, включая сам себя. Для обратного отбора используется «НЕ ... ЕСТЬ NULL» или «ЕСТЬ НЕ NULL» в зависимости от версии платформы.

Почему условие ПОДОБНО не находит подстроку?

Чаще всего забыты символы % по краям шаблона: «%текст%» ищет вхождение в любом месте, а «текст%» — только в начале строки. Также учитывайте, что специальные символы шаблона в искомой строке нужно экранировать через конструкцию СПЕЦСИМВОЛ.

Работает ли ГДЕ в пакетных запросах и временных таблицах?

Да, ГДЕ применяется в каждом запросе пакета независимо. При помещении данных во временную таблицу условие лучше ставить на этапе её наполнения — тогда в последующих запросах пакета обрабатывается меньше строк.

Как отфильтровать по элементу справочника со всеми подгруппами?

Используйте конструкцию В ИЕРАРХИИ: ГДЕ Товары.Номенклатура В ИЕРАРХИИ(&Группа). В параметр передаётся ссылка на группу, и в выборку попадут все элементы этой группы и вложенных подгрупп любого уровня.

Влияет ли порядок условий в ГДЕ на скорость?

Для СУБД, на которых работает 1С, оптимизатор сам выбирает порядок проверки условий, поэтому перестановка строк внутри ГДЕ обычно ничего не даёт. Реально влияет на скорость перенос условий в параметры виртуальных таблиц и наличие подходящих индексов по полям отбора.

Итог

Что важно запомнить

ГДЕ фильтрует строки до группировки, ИМЕЮЩИЕ — итоги после неё. Условия по периоду и измерениям регистров передавайте в параметры виртуальных таблиц. Значения подставляйте только через параметры, следите за типами операндов и расставляйте скобки при сочетании И и ИЛИ. Пустой результат при корректном синтаксисе — признак несовпадения типов или логики условия.