Работа с данными в платформе 1С:Предприятие немыслима без понимания того, как извлекать информацию из базы. Запросы являются фундаментальным инструментом разработчика, позволяющим получать выборки необходимых сведений с высокой скоростью и гибкостью. В отличие от стандартных механизмов выборки, язык запросов 1С обладает собственным синтаксисом, напоминающим SQL, но адаптированным под объекты метаданных платформы.

Правильно составленный запрос позволяет не просто получить список документов или справочников, но и выполнить сложные агрегации, объединения и фильтрацию прямо на уровне базы данных. Это критически важно для производительности системы, особенно при работе с большими объемами данных. Ошибки в построении запроса могут привести к существенному замедлению работы программы или получению некорректных результатов.

В данной статье мы детально разберем структуру языка запросов 1С, рассмотрим основные операторы и научимся оптимизировать код для максимальной эффективности. Вы узнаете, как использовать временные таблицы, работать с объединениями и применять специальные функции для анализа данных.

Базовая структура запроса и синтаксис

Любой запрос в 1С начинается с ключевого слова ВЫБРАТЬ, за которым следует перечень полей, которые необходимо получить в результате выполнения. Синтаксис строго требует указания источника данных через оператор ИЗ. Без этого конструкция будет считаться невалидной и вызовет ошибку компиляции.

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

Рассмотрим простейший пример получения списка номенклатуры из справочника:

ВЫБРАТЬ

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

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

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

ИЗ

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

Здесь мы явно указываем, какие именно поля нам нужны. Использование звездочки * хотя и допустимо в некоторых случаях, считается дурным тоном в профессиональной разработке, так как увеличивает объем передаваемых данных без необходимости. Всегда явно перечисляйте требуемые поля.

💡

Используйте псевдонимы таблиц (КАК) даже для одиночных выборок — это упрощает последующее добавление соединений и делает код унифицированным.

Обратите внимание на регистр ключевых слов. Хотя платформа 1С нечувствительна к регистру в большинстве случаев, соблюдение единого стиля написания (например, все ключевые слова заглавными буквами) значительно облегчает чтение кода коллегами.

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

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

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

☑️ Проверка условий фильтрации

Выполнено: 0 / 4

Частой задачей является выборка документов за определенный период. Для этого поля типа Дата сравниваются с граничными значениями. Важно правильно учитывать время в дате, чтобы не потерять часть документов, созданных в последние секунды дня.

ВЫБРАТЬ

РеализацияТоваровУслуг.Ссылка,

РеализацияТоваровУслуг.Дата,

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

ИЗ

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

ГДЕ

РеализацияТоваровУслуг.Дата МЕЖДУ &НачалоПериода И &КонецПериода

И РеализацияТоваровУслуг.Проведен = ИСТИНА

В примере выше используются параметры запроса, обозначенные символом амперсанда &. Это лучший способ передачи внешних значений в запрос, так как он защищает от инъекций и позволяет системе кэшировать план выполнения. Никогда не подставляйте значения переменных напрямую в текст запроса через конкатенацию строк.

⚠️ Внимание: При фильтрации по полям составных типов (например, "ЛюбаяСсылка") убедитесь, что вы сравниваете их с совместимыми типами данных, иначе условие может игнорироваться оптимизатором или работать некорректно.

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

Соединение таблиц и типы объединений

Реальные бизнес-задачи редко требуют данных только из одной таблицы. Чаще всего необходимо связать документ со справочником контрагентов или получить остатки товаров из регистра накопления. Для этого в языке запросов 1С предусмотрены различные виды соединений.

Самым распространенным является ЛЕВОЕ СОЕДИНЕНИЕ (LEFT JOIN). Оно позволяет получить все записи из левой таблицы и подходящие записи из правой. Если соответствия нет, поля правой таблицы заполняются значениями NULL. Это критически важно при построении отчетов, где нужно показать документы даже без привязанного менеджера.

📊 Какое соединение вы используете чаще всего?
ЛЕВОЕ СОЕДИНЕНИЕ
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
ПОЛНОЕ СОЕДИНЕНИЕ
Я пока не использую соединения

Внутреннее соединение (ВНУТРЕННЕЕ СОЕДИНЕНИЕ) возвращает только те записи, для которых есть соответствие в обеих таблицах. Это работает как фильтр: если у документа не заполнено поле "Контрагент", такой документ не попадет в выборку при использовании этого типа соединения.

Тип соединения Описание Результат при отсутствии связи
ЛЕВОЕ Все слева + совпадения справа NULL в полях правой таблицы
ВНУТРЕННЕЕ Только совпадения Запись исключается из выборки
ПОЛНОЕ Все записи из обеих таблиц NULL в полях той таблицы, где нет связи

При использовании соединений всегда указывайте условие связи после ключевого слова ПО. Обычно это равенство ссылок или ключевых полей. Неправильное условие соединения может привести к декартовому произведению, когда количество строк в результате вырастет в разы, что "повесит" базу данных.

Что такое декартово произведение?

Это ситуация, когда каждая строка одной таблицы соединяется с каждой строкой другой таблицы. Если в таблицах по 1000 записей, результат составит 1 000 000 строк. Это частая причина падения производительности.

Группировка и агрегатные функции

Для формирования итоговых отчетов и сводных данных необходимо уметь группировать информацию. Оператор СГРУППИРОВАТЬ ПО позволяет объединять строки с одинаковыми значениями в указанных полях. Вместе с ним используются агрегатные функции для вычисления сумм, количеств и средних значений.

Основные агрегатные функции в 1С включают СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ и СРЕДНЕЕ. Важно понимать, что в секции ВЫБРАТЬ могут присутствовать только те поля, которые указаны в группировке, либо поля, обернутые в агрегатные функции.

ВЫБРАТЬ

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

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

СУММА(Продажи.Сумма) КАК ОбщаяСумма

ИЗ

РегистрНакопления.Продажи КАК Продажи

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

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

Если вы попытаетесь вывести поле, не участвующее в группировке и не агрегированное функцией, система выдаст ошибку о неверном использовании поля. Это правило строго контролируется компилятором запросов.

💡

Порядок полей в операторе СГРУППИРОВАТЬ ПО влияет на порядок сортировки результата, если явно не указан оператор УПОРЯДОЧИТЬ ПО.

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

⚠️ Внимание: Фильтрация в операторе ГДЕ выполняется ДО группировки, а в ИМЕЮЩИЕ — ПОСЛЕ. Путать их нельзя, так как это приведет либо к ошибке синтаксиса, либо к неверной логике отбора.

Объединение результатов нескольких запросов

Иногда требуется получить единый список данных из разных источников, имеющих схожую структуру. Например, нужно вывести в один отчет остатки товаров на основном складе и на складе брака. Для таких целей служит оператор ОБЪЕДИНИТЬ.

При использовании объединения количество и типы полей в каждой части запроса должны строго совпадать. Система автоматически приводит типы к общим, но явное несоответствие (например, строка и число в одной колонке) вызовет ошибку выполнения. Имена полей в итоговом результате берутся из первого запроса в цепочке.

Существует два режима объединения: с удалением дублей и без. По умолчанию используется ОБЪЕДИНИТЬ РАЗЛИЧНЫЕ, что означает удаление полностью идентичных строк. Если вам нужно сохранить все записи, даже повторяющиеся, используйте ключевое слово ОБЪЕДИНИТЬ ВСЕ. Второй вариант работает быстрее, так как не требует проверки на уникальность.

ВЫБРАТЬ

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

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

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ОстаткиНаОсновном

ПО Номенклатура.Ссылка = ОстаткиНаОсновном.Номенклатура

И ОстаткиНаОсновном.Склад = &ОсновнойСклад

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ

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

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

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ОстаткиНаБраке

ПО Номенклатура.Ссылка = ОстаткиНаБраке.Номенклатура

И ОстаткиНаБраке.Склад = &СкладБрака

Каждая часть объединения должна быть корректным самостоятельным запросом. Вы можете использовать параметры, временные таблицы и соединения внутри каждой части независимо друг от друга.

💡

Если после объединения нужно отсортировать данные или наложить общий фильтр, оберните весь блок объединения в временную таблицу или используйте скобки, хотя в 1С предпочтительнее первый вариант для читаемости.

Временные таблицы и оптимизация

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

Синтаксически временная таблица создается путем добавления символа # в конце имени таблицы в предложении ПОМЕСТИТЬ. После этого к этой таблице можно обращаться в последующих запросах в рамках той же сессии, как к обычной таблице базы данных.

Использование временных таблиц имеет несколько весомых преимуществ. Во-первых, это упрощение отладки: вы можете проверить результат каждого этапа отдельно. Во-вторых, это возможность наложения индексов на промежуточные данные, что ускоряет последующие соединения. В-третьих, это снижение нагрузки на основную базу данных за счет уменьшения сложности плана выполнения одного гигантского запроса.

⚠️ Внимание: Временные таблицы существуют только в рамках текущей сессии пользователя. После завершения работы с объектом запроса или закрытия соединения они автоматически уничтожаются. Не пытайтесь обратиться к ним из другого сеанса.

Однако не стоит злоупотреблять этим механизмом. Создание лишних временных таблиц приводит к потреблению оперативной памяти сервера. Если запрос можно написать в один этап без потери производительности, лучше так и сделать. Использование временных таблиц оправдано при сложной многоступенчатой логике или при работе с очень большими наборами данных, требующими многократного обращения.

// Создаем временную таблицу

ВЫБРАТЬ

Документ.Ссылка,

Документ.Сумма

ПОМЕСТИТЬ ВТ_Продажи

ИЗ

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

ГДЕ

Документ.Сумма > 10000;

// Используем временную таблицу в следующем запросе

ВЫБРАТЬ

ВТ_Продажи.Ссылка,

Контрагенты.Наименование

ИЗ

ВТ_Продажи КАК ВТ_Продажи

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты

ПО ВТ_Продажи.Контрагент = Контрагенты.Ссылка

Помните о разделителях. Каждый запрос, создающий временную таблицу или использующий её, должен быть разделен точкой с запятой ;, если они выполняются в одном пакете. В коде 1С это обычно реализуется через добавление нескольких запросов в объект Запрос или выполнением их по очереди.

Как увидеть план выполнения запроса?

В Конфигураторе при отладке можно включить отображение плана выполнения запроса. Это покажет, какие индексы используются и какие таблицы сканируются полностью, что поможет найти узкие места.

Частые ошибки и лучшие практики

Даже опытные разработчики допускают ошибки при написании запросов, которые могут стоить системе производительности. Одна из самых распространенных проблем — отсутствие условий в соединениях или фильтрации по неиндексируемым полям. Это заставляет базу данных перебирать миллионы записей вместо точного поиска.

Всегда старайтесь фильтровать данные как можно раньше, в самом первом запросе или в условиях соединения. Не загружайте в приложение лишние данные, чтобы отфильтровать их уже средствами языка 1С (циклами по коллекции). Это правило "фильтрации на стороне базы" является золотым стандартом оптимизации.

Избегайте использования функций в условиях оператора ГДЕ, применяемых к полям таблиц. Например, конструкция ГДЕ Год(Дата) = 2026 является неоптимальной, так как функция применяется к каждой строке, что отключает использование индекса по дате. Лучше использовать диапазон дат: ГДЕ Дата МЕЖДУ ....

💡

Главное правило оптимизации: чем меньше данных проходит через каждый этап запроса, тем быстрее он работает. Фильтруйте, соединяйте и группируйте на стороне СУБД.

Регулярно проводите аудит ваших запросов с помощью встроенных инструментов мониторинга производительности 1С. Они позволяют выявить "тяжелые" запросы, которые выполняются дольше допустимого порога, и проанализировать их текст для поиска причин замедления.

Как передать параметр в запрос из кода 1С?

Для передачи параметра необходимо получить объект параметра из коллекции Запрос.Параметры по имени, указанному в тексте запроса (без амперсанда), и установить его значение свойством Установить. Например: Запрос.Параметры.Установить("НачалоПериода", НачалоДня(Сегодня()));.

В чем разница между ВЫБРАТЬ РАЗЛИЧНЫЕ и просто ВЫБРАТЬ?

Ключевое слово РАЗЛИЧНЫЕ указывает системе убрать дублирующиеся строки из результата выборки. Это требует дополнительных ресурсов на сортировку и сравнение. Если вы уверены, что дублей быть не может (например, выбираете по уникальному ключу), лучше не использовать это слово для ускорения работы.

Можно ли использовать запросы для изменения данных?

Нет, язык запросов 1С предназначен только для чтения данных (SELECT). Для изменения, вставки или удаления записей необходимо использовать объекты доступа к данным (МенеджерЗаписи, НаборЗаписей) или специальные операторы языка, не являющиеся частью синтаксиса запроса.

Что делать, если запрос возвращает пустой результат?

Проверьте условия в операторе ГДЕ и ПО. Убедитесь, что типы данных параметров совпадают с типами полей. Попробуйте убрать условия по одному, чтобы найти то, которое отсекает все данные. Также проверьте права доступа пользователя к используемым таблицам.

Как экранировать специальные символы в строковых константах?

В строковых литералах внутри запроса одинарная кавычка экранируется путем удвоения. Например, чтобы найти текст "Иванов", нужно написать 'Иванов'. Если в тексте есть кавычка, например "О'Лири", запрос будет выглядеть как 'О''Лири'.