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

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

Что такое SQL-запросы в 1С и как с ними работать

Разбираем, что такое SQL-запросы в 1С, чем язык запросов 1С отличается от классического SQL, как писать выборки, соединения и итоги с примерами кода.

Когда говорят об SQL-запросах в 1С, чаще всего имеют в виду встроенный язык запросов платформы. Он внешне похож на классический SQL: те же слова ВЫБРАТЬ, ИЗ, ГДЕ, СГРУППИРОВАТЬ ПО. Но это не настоящий SQL — это отдельный язык, который платформа 1С сама переводит в команды для конкретной СУБД: Microsoft SQL Server, PostgreSQL, Oracle или встроенной файловой базы.

Такое решение сделано намеренно. Разработчик пишет запрос один раз, а платформа сама адаптирует его под ту базу данных, на которой работает предприятие. Не нужно знать диалекты разных СУБД и переписывать код при переезде с файловой базы на клиент-серверный вариант.

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

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

Главное отличие — назначение. Классический SQL умеет читать и изменять данные (INSERT, UPDATE, DELETE). Язык запросов 1С предназначен только для чтения: получить выборку, посчитать итоги, соединить таблицы. Изменение данных выполняется объектными средствами платформы — через документы, справочники, регистры.

Второе отличие — уровень абстракции. В запросе 1С вы обращаетесь к объектам метаданных: Справочник.Номенклатура, Документ.РеализацияТоваровУслуг, РегистрНакопления.Продажи. Вы не знаете (и не должны знать), как называются физические таблицы и поля в СУБД. Платформа сама строит соответствие.

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

Из чего состоит запрос: основные конструкции

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

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

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

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

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

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

Отдельно стоит упомянуть ПЕРВЫЕ n — аналог TOP в SQL, который ограничивает число возвращаемых строк, и РАЗЛИЧНЫЕ — аналог DISTINCT для устранения дублей. Эти конструкции важны для производительности: если нужны только уникальные значения, лучше отсечь дубли на уровне запроса, а не перебором в коде.

Как выполнить запрос из кода 1С

Запрос в коде — это объект встроенного языка. Типовая последовательность: создать объект Запрос, присвоить текст, установить параметры, выполнить и обработать результат. Параметры всегда передаются через амперсанд — так безопасно и быстрее, чем подстановка строк.

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

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

"ВЫБРАТЬ

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

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

|ИЗ

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

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

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

Запрос.УстановитьПараметр("Начало", НачалоМесяца(ТекущаяДатаСеанса()));

Запрос.УстановитьПараметр("Конец", КонецМесяца(ТекущаяДатаСеанса()));

Результат = Запрос.Выполнить().Выгрузить();

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

Порядок выполнения запроса в коде
  1. 1
    Создайте объект: Запрос = Новый Запрос
  2. 2
    Заполните свойство Текст на языке запросов
  3. 3
    Установите все параметры через УстановитьПараметр()
  4. 4
    Вызовите Выполнить() и получите результат
  5. 5
    Обработайте через Выгрузить() или Выбрать()

Соединения, объединения и временные таблицы

Соединения работают как в SQL: ЛЕВОЕ, ПРАВОЕ, ВНУТРЕННЕЕ и ПОЛНОЕ соединение по условию. Левое соединение — самое частое в учётных задачах: например, взять весь справочник номенклатуры и подтянуть остатки, даже если по части товаров остатков нет (там будет NULL, который стоит обернуть в ЕСТЬNULL).

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

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

Консоль запросов и отладка

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

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

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

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

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

Число строк в выборке
Норма

Совпадает с ожидаемым количеством объектов

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

Строк больше, чем объектов — дубли из-за соединения

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

Сходятся с типовым отчётом конфигурации

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

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

Значения NULL
Норма

Пустые поля обработаны через ЕСТЬNULL

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

NULL попадает в расчёты и ломает арифметику

Типичные ошибки и производительность

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

Вторая частая проблема — отсутствие параметров виртуальных таблиц. Конструкция РегистрНакопления.Продажи.Обороты без указания периода и отборов заставляет СУБД считать обороты по всей таблице, а потом отбрасывать лишнее. Всегда передавайте период и условия в параметры виртуальной таблицы.

Третья группа ошибок — логические: использование УПОРЯДОЧИТЬ ПО по полю, которого нет в выборке, группировка без агрегатных функций, сравнение с NULL через равенство (нужно ЕСТЬ NULL), а также подстановка пользовательского ввода прямо в текст запроса вместо параметров.

Типичные ошибки
01
Запрос внутри цикла — сотни обращений к СУБД вместо одного
02
Виртуальная таблица без параметров периода и отбора — полный расчёт по всей таблице
03
Подстановка строк в текст запроса вместо параметров — риск ошибок и инъекций
04
Обращение через точку в условиях ГДЕ — скрытые соединения и падение скорости
05
Игнорирование NULL в соединениях — неверные итоги и сбои арифметики

Где запросы применяются на практике

Основные сценарии использования языка запросов: динамические списки форм, отчёты на системе компоновки данных (СКД), обработки загрузки и выгрузки данных, проведение документов (чтение остатков для списания), регламентные задания и обмены данными.

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

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

FAQ: частые вопросы о запросах в 1С

Можно ли писать в 1С настоящий SQL?

Напрямую в коде — нет, платформа понимает только свой язык запросов. Обойти это можно через внешние компоненты или COM-доступ к СУБД, но такой путь применяется редко, только для чтения и требует глубокого понимания структуры хранения данных 1С.

Что лучше для отчёта: запрос с кодом или СКД?

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

Почему запрос в консоли работает быстро, а в коде медленно?

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

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

Используйте виртуальную таблицу Обороты или ОстаткиИОбороты с параметрами начала и конца периода: РегистрНакопления.Продажи.Обороты(&Начало, &Конец, , ). Параметры передаются через УстановитьПараметр до выполнения запроса.

Чем ОБЪЕДИНИТЬ отличается от ОБЪЕДИНИТЬ ВСЕ?

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

Нужно ли знать SQL, чтобы писать запросы в 1С?

Не обязательно, но знание основ SQL (соединения, группировки, подзапросы) сильно помогает: логика языка запросов 1С построена на тех же принципах. Обратное тоже верно — опыт запросов в 1С облегчает изучение классического SQL.

Итог

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

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