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

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

Как перевести запрос SQL в 1С

Как перевести SQL-запрос на язык запросов 1С: соответствие операторов, соединения, группировки, виртуальные таблицы, типичные ошибки и проверка результата.

Разработчики, приходящие в 1С из мира классических баз данных, часто пытаются переносить готовые SQL-запросы напрямую. Это приводит к ошибкам: язык запросов 1С внешне похож на SQL, но работает не с физическими таблицами СУБД, а с объектами метаданных — справочниками, документами, регистрами. Поэтому «перевод» запроса — это не подмена ключевых слов, а перенос логики выборки на другую модель данных.

Хорошая новость в том, что большинство конструкций имеют прямые аналоги: SELECT, WHERE, JOIN, GROUP BY, ORDER BY переводятся почти один в один. Сложности начинаются там, где SQL опирается на хранимые процедуры, оконные функции, подзапросы с LIMIT или прямую работу с датами на уровне СУБД — в 1С для этого существуют собственные механизмы.

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

Чем язык запросов 1С отличается от SQL

Язык запросов 1С — декларативный диалект, синтаксически близкий к SQL, но обращающийся не к физическим таблицам, а к сущностям конфигурации: Справочник.Номенклатура, Документ.РеализацияТоваровУслуг, РегистрНакопления.ТоварыНаСкладах. Платформа сама преобразует такой запрос в SQL для конкретной СУБД (MS SQL Server, PostgreSQL, Oracle, IBM Db2), и разработчик не управляет этим уровнем напрямую.

Из этого следуют ключевые ограничения. В языке запросов 1С нет INSERT, UPDATE и DELETE — изменение данных выполняется только объектными средствами. Нет хранимых процедур, триггеров, оконных функций и оператора LIMIT — вместо него используется конструкция ПЕРВЫЕ n. Зато есть механизмы, которых нет в чистом SQL: виртуальные таблицы регистров, итоги, разыменование полей через точку.

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

Сопоставление таблиц и полей

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

Поля переводятся по именам реквизитов, а не по физическим колонкам СУБД. Например, колонка Descr в таблице справочника на уровне СУБД соответствует реквизиту Наименование. Стандартные реквизиты (Ссылка, Код, Дата, Номер, Проведен) доступны без дополнительных соединений, тогда как в SQL для получения связанных данных часто нужен JOIN.

Особенность 1С — разыменование: через точку можно обратиться к реквизиту связанного объекта, например Товары.Номенклатура.Артикул. В SQL аналогичная задача решалась бы соединением с таблицей номенклатуры. Разыменование удобно, но при массовом использовании в условиях и соединениях замедляет запрос — платформа всё равно строит неявные соединения.

Конструкция SQLАналог в 1СКомментарий
SELECT ... FROM tableВЫБРАТЬ ... ИЗ ОбъектМетаданныхТаблица указывается как объект конфигурации
WHEREГДЕСинтаксис условий почти совпадает
LEFT / INNER JOINЛЕВОЕ / ВНУТРЕННЕЕ СОЕДИНЕНИЕСемантика аналогична
GROUP BY + SUMСГРУППИРОВАТЬ ПО + СУММААгрегатные функции совпадают
ORDER BYУПОРЯДОЧИТЬ ПОЕсть также АВТОУПОРЯДОЧИВАНИЕ
LIMIT / TOPПЕРВЫЕ nУказывается сразу после ВЫБРАТЬ
CASE WHENВЫБОР КОГДА ... ТОГДА ... КОНЕЦПолный аналог условного выражения
IS NULLЕСТЬ NULLПроверка на неопределённое значение

Перевод базовой выборки: пример

Рассмотрим типовой SQL-запрос, выбирающий проведённые документы продажи за период с отбором по контрагенту:

SELECT Doc.Number, Doc.Date, Contr.Name, Doc.Total

FROM SalesDoc AS Doc

INNER JOIN Contractors AS Contr ON Contr.ID = Doc.ContractorID

WHERE Doc.Posted = 1 AND Doc.Date BETWEEN @D1 AND @D2

ORDER BY Doc.Date

Эквивалент на языке запросов 1С выглядит так:

ВЫБРАТЬ

Реализация.Номер,

Реализация.Дата,

Реализация.Контрагент.Наименование КАК Контрагент,

Реализация.СуммаДокумента КАК Сумма

ИЗ

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

ГДЕ

Реализация.Проведен

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

УПОРЯДОЧИТЬ ПО

Реализация.Дата

Обратите внимание на три момента. Во-первых, соединение с контрагентами заменено разыменованием Контрагент.Наименование. Во-вторых, параметры в 1С обозначаются амперсандом (&НачалоПериода), а не @. В-третьих, агрегат «сумма документа» здесь — обычный реквизит, а не результат SUM по табличной части, как это часто бывает в SQL-моделях.

bsl
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 10 Номенклатура.Наименование ИЗ Справочник.Номенклатура КАК Номенклатура";
Результат = Запрос.Выполнить().Выгрузить();

Соединения и подзапросы

Соединения переводятся почти дословно: INNER JOIN становится ВНУТРЕННИМ СОЕДИНЕНИЕМ, LEFT JOIN — ЛЕВЫМ, условие связи пишется после ПО. Важное отличие — в 1С условие соединения должно быть равенством полей; неравенства и произвольные выражения в секции ПО не поддерживаются так свободно, как в SQL, и сложные условия выносятся в секцию ГДЕ.

Вложенные запросы в 1С допустимы как в секции ИЗ, так и в условиях (В (ВЫБРАТЬ ...)). Однако при переводе многоуровневых подзапросов из SQL стоит оценить, не заменить ли их временными таблицами. Пакетный запрос с временными таблицами (ПОМЕСТИТЬ ВТ) читается проще и часто работает быстрее, потому что платформа материализует промежуточный результат один раз.

Типичный приём при переводе: SQL-подзапрос, вычисляющий максимальную дату документа по контрагенту, в 1С обычно заменяется соединением с виртуальной таблицей или группировкой во временной таблице, а не коррелированным подзапросом — коррелированные подзапросы в 1С существенно медленнее.

Порядок перевода запроса
  1. 1
    Разберите SQL-запрос: выпишите источники данных, условия, соединения, агрегаты
  2. 2
    Сопоставьте каждой таблице объект метаданных или виртуальную таблицу регистра
  3. 3
    Перепишите выборку: ВЫБРАТЬ, ИЗ, ГДЕ, соединения, СГРУППИРОВАТЬ ПО
  4. 4
    Замените переменные на параметры с амперсандом и задайте их через УстановитьПараметр
  5. 5
    Проверьте результат в консоли запросов на копии базы и сравните выборку с оригиналом

Группировки, итоги и виртуальные таблицы

Агрегатные функции — СУММА, КОЛИЧЕСТВО, МАКСИМУМ, МИНИМУМ, СРЕДНЕЕ — совпадают по смыслу с SQL. Отличие в иерархических итогах: конструкция ИТОГИ ПО с ОБЩИЕ и ТОЛЬКО ИЕРАРХИЯ не имеет прямого аналога в стандартном SQL (ближайший эквивалент — GROUPING SETS / ROLLUP), и при переводе из SQL такие блоки просто добавляются заново, если нужны промежуточные суммы.

Главная замена SQL-агрегации — виртуальные таблицы регистров. Если в SQL вы группируете таблицу движений, чтобы получить остаток на дату, в 1С вместо этого обращаются к РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад). Параметры виртуальной таблицы (период, условия) указываются в скобках — это критично для производительности: отбор внутри виртуальной таблицы выполняется до соединения, а не после.

Для регистров сведений аналогом запросов вида «последнее значение на дату» (в SQL — подзапрос с MAX по периоду или оконная функция ROW_NUMBER) служит виртуальная таблица СрезПоследних, а для первого значения — СрезПервых. Это одна из самых частых замен при переводе аналитических запросов.

Проверка результата и типичные ошибки

Проверять переведённый запрос удобнее всего в консоли запросов на копии рабочей базы: выполните оригинальный SQL на стороне СУБД (если есть доступ) и переведённый запрос в 1С, затем сравните число строк и контрольные суммы по ключевым полям. Совпадение количества записей — минимальный критерий; далее сверьте агрегаты по нескольким случайным группам.

Признаки корректного перевода: одинаковая кардинальность выборок, совпадающие итоговые суммы, отсутствие дублей, которые в SQL отсекались DISTINCT. Если строк в 1С-выборке больше — почти наверняка потеряно условие соединения или разыменование породило декартово произведение через табличную часть.

Типичные ошибки
01
Соединение с табличной частью без отбора по ссылке — строки документа перемножаются, суммы завышаются
02
Отбор по виртуальной таблице в секции ГДЕ вместо параметров — резкое падение производительности
03
Перенос NULL-логики без учёта того, что в 1С у составных типов вместо NULL могут быть пустые ссылки
04
Использование разыменования в условиях соединения — платформа строит скрытые соединения, запрос деградирует
05
Попытка перевести LIMIT постраничной выборки без ПЕРВЫЕ — выборка тянет миллионы строк в память

Отдельный класс проблем — составные типы. В SQL колонка либо NULL, либо значение одного типа. В 1С реквизит составного типа может содержать пустую ссылку другого типа, и сравнение = &Параметр с параметром не того типа молча вернёт пустой результат. При переводе проверяйте типы параметров через ВЫРАЗИТЬ(... КАК ...) там, где это необходимо.

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

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

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

Совпадает с исходной SQL-выборкой

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

Строк больше — потеряно условие соединения или дубли из табличной части

Суммы по группам
Норма

Контрольные итоги по 3–5 группам совпадают

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

Суммы кратно завышены — декартово произведение

Время выполнения
Норма

Запрос выполняется за секунды на рабочем объёме

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

Минуты на копии — отбор не в параметрах виртуальной таблицы

Когда перевод не требуется: прямой доступ к СУБД

В некоторых сценариях переводить запрос не нужно вовсе. Если задача — интеграционная выгрузка, аналитика во внешнем хранилище или разовая миграция, допустимо выполнить SQL-запрос напрямую к базе через ADO или внешние источники данных. Это законный вариант, но с жёсткими ограничениями.

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

Для чтения предпочтительнее внешние источники данных или выгрузка через штатные механизмы: язык запросов покрывает подавляющее большинство аналитических задач, а его результат корректно работает с правами доступа (RLS), чего прямой SQL не гарантирует.

Итог

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

Перевод SQL в 1С — это перенос логики на объекты метаданных, а не замена ключевых слов. Основные операторы имеют прямые аналоги, агрегация по регистрам заменяется виртуальными таблицами с параметрами, а результат обязательно сверяется с оригиналом по числу строк и контрольным суммам.

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

Существует ли автоматический конвертер SQL в язык запросов 1С?

Полноценных конвертеров нет: SQL оперирует физическими таблицами, а язык 1С — метаданными, и автоматически установить это соответствие нельзя. Консоль запросов и конструктор помогают собирать запрос по метаданным, но логику переводит разработчик.

Как перевести SQL-запрос с оконными функциями?

Оконных функций в языке запросов 1С нет. Типовые задачи решаются иначе: нумерация строк — обходом выборки в коде, нарастающий итог — запросом с соединением по неравенству или постобработкой, «последнее значение в группе» — виртуальными таблицами СрезПоследних или группировкой с МАКСИМУМ.

Можно ли выполнить произвольный SQL из кода 1С?

К собственной базе — нет, платформа принимает только язык запросов. К внешней базе — да, через COM-соединение с ADO или внешние источники данных, но только для чтения и только к сторонним системам, а не к базе 1С в обход платформы.

Как перевести условие с датами, если в SQL используются функции DATEADD и DATEDIFF?

В 1С есть свои функции работы с датами: ДОБАВИТЬКДАТЕ и РАЗНОСТЬДАТ с указанием единицы измерения (СЕКУНДА, ДЕНЬ, МЕСЯЦ). Также доступны НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА для округления дат, что заменяет типовые SQL-приёмы с усечением времени.

Почему переведённый запрос возвращает меньше строк, чем оригинальный SQL?

Чаще всего дело в параметрах составного типа или в неявном отборе: если параметр имеет тип, не совпадающий с типом поля, сравнение не срабатывает. Проверьте типы через ВЫРАЗИТЬ, а также убедитесь, что соединение не стало внутренним там, где в SQL было левое.

Где отлаживать переведённый запрос?

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