Переход с классических СУБД (MS SQL, Oracle, PostgreSQL) на платформу 1С часто вызывает у опытных разработчиков легкое недоумение. С одной стороны, они видят знакомые конструкции выбора, фильтрации и объединения данных. С другой стороны, жесткая привязка к абстрактным объектам метаданных вместо привычных физических таблиц создает ощущение «информационного вакуума». Кажется, что для написания эффективных запросов нужно сначала досконально изучить структуру сотен объектов конфигурации.
В этой статье мы подробно разберем, как устроен язык запросов 1С «под капотом», сопоставим его синтаксис с классическим SQL, проанализируем ключевые отличия и подводные камни, а также выясним, почему технический бэкграунд в SQL — это ваше главное преимущество при освоении 1С.
Для разработчика с опытом работы в СУБД важно понять ключевой факт: никакой принципиально иной магии хранения данных в 1С нет. На уровне базы данных (будь то MS SQL, PostgreSQL, IBM DB2 или Oracle) находятся точно такие же реляционные таблицы с индексами, первичными и внешними ключами.
Платформа 1С:Предприятие выступает в роли мощной, глубоко интегрированной ORM-системы (Object-Relational Mapping). Платформа берет на себя задачу трансляции понятных человеку метаданных (справочников, документов, регистров) в физические таблицы базы данных.
Давайте проанализируем, как транслируются объекты метаданных 1С в физические таблицы СУБД:
_Reference23. Каждая табличная часть справочника выносится в отдельную связанную таблицу вида _Reference23_VT54._Document112) и связанных таблиц для каждой табличной части (_Document112_VT123)._InfoReg343).Специальный транслятор платформы — SDBL (System Database Layer) — преобразует написанный вами запрос на «человеческом» языке 1С в реальный, оптимизированный SQL-код СУБД. Именно поэтому писать прямые SQL-запросы к базе данных 1С крайне не рекомендуется: структура физических таблиц (номера в именах вида _Reference23) динамически меняется при обновлении конфигурации, а СУБД в обход платформы не сможет гарантировать бизнес-логику и безопасность данных.
Если вы уже умеете писать аналитические запросы на SQL, то освоение синтаксиса 1С займет у вас буквально несколько часов. Язык запросов 1С — это фактически русифицированный (хотя поддерживается и англоязычный синтаксис) и намеренно упрощенный диалект SQL.
Давайте сопоставим базовые конструкции двух языков:
-- Классический SQL:
SELECT
t.ItemName AS Название,
SUM(t.Quantity) AS Всего
FROM
dbo.SalesTable t
WHERE
t.Status = 'Active'
GROUP BY
t.ItemName
HAVING
SUM(t.Quantity) > 10
ORDER BY
Всего DESC;
А теперь посмотрим, как эта же логика выглядит на языке запросов 1С:
// Язык запросов 1С:
ВЫБРАТЬ
Продажи.Номенклатура.Наименование КАК Название,
СУММА(Продажи.Количество) КАК Всего
ИЗ
РегистрНакопления.Продажи КАК Продажи
ГДЕ
Продажи.Статус = ЗНАЧЕНИЕ(Перечисление.Статусы.Активен)
СГРУППИРОВАТЬ ПО
Продажи.Номенклатура.Наименование
ИМЕЮЩИЕ
СУММА(Продажи.Количество) > 10
УПОРЯДОЧИТЬ ПО
Всего УБЫВ
Как видим, конструкции полностью идентичны. Оператор SELECT превращается в ВЫБРАТЬ, FROM в ИЗ, WHERE в ГДЕ, GROUP BY в СГРУППИРОВАТЬ ПО, HAVING в ИМЕЮЩИЕ, а ORDER BY в УПОРЯДОЧИТЬ ПО. Вы даже можете писать запросы в 1С на английском языке — платформа без проблем их скомпилирует.
В языке запросов 1С есть невероятно удобная для разработчика конструкция — обращение к реквизитам связанных таблиц «через точку». Например, у нас есть документ «Реализация товаров», в котором выбрана номенклатура. Нам нужно получить артикул этой номенклатуры. В 1С мы пишем:
ВЫБРАТЬ
Реализация.Номенклатура.Артикул КАК Артикул
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Реализация
Для классического SQL-разработчика это выглядит как магия. Однако под капотом транслятор платформы автоматически генерирует неявное левое соединение (LEFT JOIN) с таблицей справочника «Номенклатура» по первичному ключу (ссылке). В простых запросах это сильно экономит время, но здесь кроется опаснейшая ловушка для производительности.
Рассмотрим две проблемы, связанные с разыменованием через точку:
Проблема составных типов данных. В 1С реквизиты могут иметь составной тип (например, реквизит Регистратор в регистрах сведений или накопления может ссылаться на десятки различных видов документов). Если вы напишете в запросе:
ВЫБРАТЬ
Продажи.Регистратор.Дата КАК ДатаДокумента
ИЗ
РегистрНакопления.Продажи КАК Продажи
Платформа 1С сгенерирует в SQL-запросе неявное левое соединение со всеми таблицами документов, которые могут выступать регистраторами для данного регистра! Если в конфигурации таких документов 40 или 50, ваш итоговый SQL-запрос превратится в неповоротливого монстра с 50 соединениями, что приведет к катастрофическому падению производительности на реальных базах данных.
Решение проблемы: SQL-специалисту в 1С критически важно научиться использовать функцию ВЫРАЗИТЬ(). Она работает аналогично оператору CAST, но в контексте ссылочных типов ограничивает выборку конкретным типом, заставляя платформу делать только одно необходимое соединение. Разберем правильный пример:
ВЫБРАТЬ
ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РеализацияТоваровУслуг).Дата КАК ДатаДокумента
ИЗ
РегистрНакопления.Продажи КАК Продажи
При использовании конструкции ВЫРАЗИТЬ() платформа свяжет таблицу регистра только с одной физической таблицей документа «Реализация товаров и услуг».
Переходя на 1С, SQL-разработчик неизбежно столкнется с ограничениями платформы. Язык запросов 1С умышленно упрощен, чтобы обеспечить кроссплатформенность (совместимость с MS SQL, PostgreSQL, Oracle) и защитить базу данных от некорректных действий программиста.
Рассмотрим ключевые ограничения:
ROW_NUMBER(), RANK(), PARTITION BY или OVER(). Если вам нужно рассчитать нарастающий итог или пронумеровать строки внутри группы, вам придется решать эту задачу обходными путями. Обычно это делается с помощью левого соединения таблицы самой с собой по условию «меньше или равно» (что непроизводительно на больших объемах данных) либо путем постобработки полученной выборки во встроенном языке программирования 1С.ВЫРАЗИТЬ() не может произвольно преобразовать строку в число или дату, как это делает полноценный CAST или CONVERT в SQL. Она умеет лишь ограничивать длину строк и чисел или приводить составные ссылочные типы к простым.INSERT, UPDATE, DELETE. Запрос в 1С всегда работает исключительно на чтение (аналог SELECT). Любая запись, изменение или удаление данных в системе происходит только программно через объектную технику встроенного языка (с помощью объектов типа ДокументОбъект, СправочникОбъект, РегистрСведенийНаборЗаписей). Это гарантирует, что при записи данных обязательно отработают все транзакционные проверки и бизнес-логика системы.Для оптимизации работы с транзакционными данными в платформе 1С реализован механизм регистров. По сути, это готовые витрины данных (Data Marts). При обращении к ним платформа предоставляет так называемые виртуальные таблицы.
Например, конструкция РегистрНакопления.ТоварыНаСкладах.Остатки — это не просто красивое имя физической таблицы. Физически в СУБД хранятся таблицы движений (транзакций) и таблицы итогов (рассчитанные остатки на начало каждого месяца). Когда вы вызываете виртуальную таблицу остатков на определенную дату, платформа 1С выполняет сложнейшую математическую операцию: берет ближайшие рассчитанные итоги из таблицы агрегатов и докручивает к ним детальные движения из таблицы транзакций до указанной даты.
Давайте посмотрим на пример правильного использования параметров виртуальной таблицы:
ВЫБРАТЬ
ОстаткиТоваров.Номенклатура КАК Номенклатура,
ОстаткиТоваров.В НаличииОстаток КАК Остаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Номенклатура = &ВыбраннаяНоменклатура) КАК ОстаткиТоваров
Важное правило для SQL-разработчика: никогда не накладывайте условия на виртуальные таблицы в секции ГДЕ! Условия по измерениям (например, фильтр по номенклатуре или складу) необходимо передавать исключительно в параметры самой виртуальной таблицы (внутрь круглых скобок). В противном случае платформа сначала выберет все остатки по всем товарам из СУБД, а затем будет фильтровать их на уровне приложения, что убьет производительность всей системы.
Современные версии платформы 1С (начиная с 8.3.24 и 8.3.25) получили мощные механизмы оптимизации, которые еще больше приближают язык запросов 1С к возможностям классических СУБД. Проанализируем ключевые нововведения:
ПОМЕСТИТЬ. Начиная с версии 8.3.25, появилась конструкция ДОБАВИТЬ, которая позволяет динамически дописывать строки в уже созданную ранее временную таблицу из других источников.УникальныйИдентификатор(), позволяющая получать GUID ссылки напрямую в теле запроса к СУБД.Если вы хотите быстро освоить язык запросов 1С, рекомендуем придерживаться следующего алгоритма действий:
СрезПоследних) и регистрами накопления остатков и оборотов.Помните, что ваш опыт проектирования баз данных и написания SQL-запросов — это колоссальное преимущество. Вы уже понимаете принципы группировки, фильтрации, соединений и индексации данных. Вам остается лишь привыкнуть к русскоязычным именам полей, объектной абстракции метаданных и научиться эффективно управлять виртуальными таблицами платформы 1С.