В экосистеме платформы 1С:Предприятие язык запросов занимает центральное место, являясь основным инструментом для выборки и обработки данных. В отличие от стандартного SQL, который напрямую работает с таблицами реляционной базы данных, язык запросов 1С представляет собой надстройку, обеспечивающую независимость от конкретной СУБД. Это позволяет разработчикам писать универсальный код, который корректно выполняется как на встроенной базе файловых данных, так и на мощных серверах Microsoft SQL Server или PostgreSQL. Понимание принципов работы этого инструмента критически важно для создания производительных конфигураций.

Основная задача языка — преобразование запроса в исполняемый код конкретной базы данных с учетом специфики платформы. Вам необходимо осознавать, что написание запроса в конфигураторе или встроенном языке — это не просто обращение к таблице, а сложный процесс, включающий анализ прав доступа, интерпретацию виртуальных таблиц и оптимизацию выполнения. Язык запросов 1С строго типизирован и имеет свой собственный набор ключевых слов, функций и операторов, которые могут отличаться от привычных SQL-конструкций. Ошибки в синтаксисе или логике построения выборки часто приводят к значительному падению производительности всей информационной системы.

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

Архитектура и отличия от стандартного SQL

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

Синтаксис языка запросов 1С ближе к стандарту ANSI SQL, но имеет ряд уникальных особенностей. Например, для обозначения полей таблиц используются точки, а для псевдонимов — ключевое слово КАК. Синтаксический анализатор платформы проверяет запрос еще на этапе компиляции модуля, что позволяет отлавливать многие ошибки до запуска программы.

Еще одним важным аспектом является работа с виртуальными таблицами. Платформа предоставляет специальные конструкции для получения итоговых данных, срезов последних регистров или движений за период. Использование этих механизмов вместо ручного написания сложных группировок и соединений значительно ускоряет выполнение кода. Менеджер запросов оптимизирует такие обращения, превращая их в эффективные SQL-выражения, специфичные для текущей СУБД.

⚠️ Внимание: Прямое обращение к физическим таблицам базы данных в обход механизмов платформы (через ADO или ODBC) лишает вас преимуществ автоматического контроля прав доступа и работы с виртуальными таблицами. Используйте такой подход только в исключительных случаях для администрирования.

💡

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

Базовый синтаксис и структура SELECT

Основной оператор языка — ВЫБРАТЬ (или SELECT в английской локали). Структура запроса всегда начинается с указания полей, которые необходимо получить. В отличие от SQL, где часто используют *, в 1С рекомендуется явно перечислять необходимые поля. Это улучшает читаемость кода и позволяет платформе оптимизировать выборку, не загружая лишние данные из базы. Каждое поле может иметь псевдоним, который упрощает дальнейшую работу с результатом в коде.

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

ВЫБРАТЬ

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

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

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

ИЗ

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

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

📊 Какой стиль написания запросов вы предпочитаете?
Полностью на русском (ВЫБРАТЬ, ИЗ, ГДЕ)
Полностью на английском (SELECT, FROM, WHERE)
Смешанный стиль
Использую конструктор запросов

Соединения таблиц и типы JOIN

В реальных задачах данные редко хранятся в одной таблице. Часто требуется объединить информацию из справочника номенклатуры с данными о ценах или остатках на складе. Для этого в языке запросов 1С используются соединения. Синтаксически они аналогичны SQL, но имеют свои нюансы в написании условий соединения. Основным оператором является ЛЕВОЕ СОЕДИНЕНИЕ, которое позволяет получить все записи из левой таблицы и соответствующие им записи из правой.

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

Тип соединения Описание поведения Типичный сценарий использования
ЛЕВОЕ СОЕДИНЕНИЕ Все строки из левой таблицы + совпадения из правой Список товаров с указанием цены (если есть)
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Только строки, где есть совпадение в обеих таблицах Отчет по продажам только с указанием номенклатуры
ПОЛНОЕ СОЕДИНЕНИЕ Все строки из обеих таблиц Сверка взаиморасчетов с контрагентами
ПРАВОЕ СОЕДИНЕНИЕ Все строки из правой таблицы + совпадения из левой Используется редко, часто заменяется левым с перестановкой

При написании условий соединения важно указывать поля, по которым происходит стыковка таблиц, в секции ПО. Часто ошибкой является дублирование условий фильтрации: часть условий пишут в ПО, а часть в ГДЕ. Хотя результат может быть верным, размещение условий фильтрации связанных таблиц в секции ГДЕ обычно предпочтительнее для оптимизации, так как позволяет СУБД эффективнее использовать индексы перед выполнением соединения.

💡

Избегайте использования ПОЛНОГО СОЕДИНЕНИЯ в высоконагруженных системах без крайней необходимости. Этот тип соединения требует значительных ресурсов и часто может быть заменен комбинацией левых соединений и объединений (UNION).

Работа с временными таблицами

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

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

ПОМЕСТИТЬ ВременныеОстатки

ВЫБРАТЬ

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

СУММА(ОстаткиНоменклатуры.КоличествоОстаток) КАК Количество

ИЗ

РегистрНакопления.ОстаткиНоменклатуры.Остатки(, , ,) КАК ОстаткиНоменклатуры

ГДЕ

ОстаткиНоменклатуры.Период МЕЖДУ &НачалоПериода И &КонецПериода

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

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

.

ВЫБРАТЬ

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

ВременныеОстатки.Количество

ИЗ

ВременныеОстатки КАК ВременныеОстатки

Важно следить за количеством создаваемых временных таблиц. Чрезмерное их использование может привести к переполнению временного пространства базы данных (tempdb в MS SQL), что негативно скажется на работе всей системы в целом. Оптимизация запросов часто заключается в минимизации количества проходов по данным и объединении этапов обработки там, где это возможно без потери производительности.

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

☑️ Оптимизация работы с временными таблицами

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

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

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

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

Агрегатные функции в 1С работают аналогично SQL, но имеют некоторые особенности в работе с типами данных. Например, функция СУММА автоматически определяет тип результата в зависимости от складываемых полей. При работе с nullable-полями (полями, которые могут быть пустыми) следует быть внимательным, так как агрегатные функции обычно игнорируют пустые значения, что может исказить логику расчетов, если это не предусмотрено алгоритмом.

Особенности функции ЕСТЬNULL()

В запросах 1С часто возникает ситуация, когда нужно заменить пустое значение на ноль или другое число. Для этого используется функция ЕСТЬNULL(Значение, Замена). Она проверяет поле на пустоту и возвращает значение замены, если поле пусто. Это критически важно при математических операциях, так как сложение с пустым значением даст пустой результат.

Параметризация и защита от SQL-инъекций

Безопасность и гибкость запросов обеспечиваются через использование параметров. Вместо подстановки значений напрямую в текст запроса (конкатенация строк), следует использовать именованные параметры, начинающиеся со знака амперсанда &. Это не только защищает приложение от SQL-инъекций, но и позволяет планам выполнения запросов кэшироваться в СУБД, что значительно повышает производительность при многократном выполнении одного и того же запроса с разными данными.

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

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

⚠️ Внимание: Никогда не формируйте текст запроса путем простого сложения строк с пользовательским вводом (например, "ГДЕ Имя = '" + ВводПользователя + "'"). Это создает уязвимость безопасности и препятствует кэшированию планов выполнения запроса сервером базы данных.

💡

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

Часто задаваемые вопросы (FAQ)

В чем разница между виртуальными таблицами и обычными таблицами регистров?

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

Можно ли выполнять UPDATE или DELETE через язык запросов 1С?

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

Как ускорить медленный запрос на больших базах данных?

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

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

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

Как передать список значений в параметр запроса?

Для передачи списка значений (например, массива ссылок на документы) используйте параметр типа СписокЗначений или таблицу значений. В тексте запроса такой параметр используется в условии В (например, ГДЕ Ссылка В &СписокСсылок). Платформа автоматически раскроет этот параметр в список значений для СУБД.