Разработка и Конфигурация · 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Создайте объект: Запрос = Новый Запрос
- 2Заполните свойство Текст на языке запросов
- 3Установите все параметры через УстановитьПараметр()
- 4Вызовите Выполнить() и получите результат
- 5Обработайте через Выгрузить() или Выбрать()
Соединения, объединения и временные таблицы
Соединения работают как в SQL: ЛЕВОЕ, ПРАВОЕ, ВНУТРЕННЕЕ и ПОЛНОЕ соединение по условию. Левое соединение — самое частое в учётных задачах: например, взять весь справочник номенклатуры и подтянуть остатки, даже если по части товаров остатков нет (там будет NULL, который стоит обернуть в ЕСТЬNULL).
ОБЪЕДИНИТЬ складывает строки из нескольких выборок в одну. Вариант ОБЪЕДИНИТЬ ВСЕ работает быстрее, потому что не устраняет дубли, — используйте его, когда дубли заведомо невозможны или не мешают.
Временные таблицы — мощный инструмент сложных запросов. Конструкция ПОМЕСТИТЬ В ИмяТаблицы сохраняет промежуточную выборку, а пакетный запрос выполняет несколько операторов подряд. Для работы с временными таблицами используется объект МенеджерВременныхТаблиц. Это позволяет разбить громоздкую логику на понятные шаги и ускорить выполнение.
Консоль запросов и отладка
Писать запросы вслепую, сразу в модуле, — плохая практика. Стандартный инструмент разработчика — консоль запросов: внешняя обработка, которая позволяет набирать текст запроса, подставлять параметры и сразу видеть результат на реальных данных. В конфигураторе также есть конструктор запроса, который строит текст визуально.
Типовой цикл работы: набросать запрос в консоли, проверить на копии рабочей базы, добиться правильных итогов, затем перенести текст в код и заменить литеральные значения параметрами. Это сокращает число ошибок и ускоряет разработку.
При отладке полезно проверять запрос по частям: сначала источник без отборов, потом с условиями, потом с группировкой. Если итоги «не сходятся», чаще всего виноваты дублирующиеся строки в соединении (декартово размножение) или неверный период виртуальной таблицы.
Как проверить результат запроса
Совпадает с ожидаемым количеством объектов
Строк больше, чем объектов — дубли из-за соединения
Сходятся с типовым отчётом конфигурации
Суммы завышены кратно — размножение строк
Пустые поля обработаны через ЕСТЬNULL
NULL попадает в расчёты и ломает арифметику
Типичные ошибки и производительность
Самая дорогая ошибка — запрос в цикле. Если внутри перебора строк выполняется запрос к базе, при тысяче строк получится тысяча обращений к СУБД. Правильный подход — один запрос с соединением или временной таблицей, который получает все нужные данные сразу.
Вторая частая проблема — отсутствие параметров виртуальных таблиц. Конструкция РегистрНакопления.Продажи.Обороты без указания периода и отборов заставляет СУБД считать обороты по всей таблице, а потом отбрасывать лишнее. Всегда передавайте период и условия в параметры виртуальной таблицы.
Третья группа ошибок — логические: использование УПОРЯДОЧИТЬ ПО по полю, которого нет в выборке, группировка без агрегатных функций, сравнение с NULL через равенство (нужно ЕСТЬ NULL), а также подстановка пользовательского ввода прямо в текст запроса вместо параметров.
Где запросы применяются на практике
Основные сценарии использования языка запросов: динамические списки форм, отчёты на системе компоновки данных (СКД), обработки загрузки и выгрузки данных, проведение документов (чтение остатков для списания), регламентные задания и обмены данными.
В СКД запрос — это источник данных схемы компоновки. Пользовательские отборы и группировки накладываются поверх него, поэтому запрос для СКД обычно пишут шире: без жёстких отборов, которые логичнее оставить настройкам отчёта.
Прямой доступ к СУБД средствами самого SQL-сервера в обход платформы допустим только для чтения и только понимающему специалисту: структура таблиц 1С не публична и может меняться при обновлении платформы. Запись в базу напрямую через SQL нарушает целостность данных и лицензионные требования.
FAQ: частые вопросы о запросах в 1С
Можно ли писать в 1С настоящий SQL?
Напрямую в коде — нет, платформа понимает только свой язык запросов. Обойти это можно через внешние компоненты или COM-доступ к СУБД, но такой путь применяется редко, только для чтения и требует глубокого понимания структуры хранения данных 1С.
Что лучше для отчёта: запрос с кодом или СКД?
Если отчёт нужен пользователям с настройками отборов и группировок — выбирайте СКД, она даёт гибкость без доработок. Программный запрос оправдан для узких служебных задач: обработок, обменов, проверок данных.
Почему запрос в консоли работает быстро, а в коде медленно?
Частая причина — разные параметры или неявные соединения через точку, которые в коде появляются из-за более широких условий. Также проверьте, не выполняется ли запрос в цикле и не включён ли на сервере другой план запроса из-за устаревшей статистики СУБД.
Как выбрать данные за период из регистра накопления?
Используйте виртуальную таблицу Обороты или ОстаткиИОбороты с параметрами начала и конца периода: РегистрНакопления.Продажи.Обороты(&Начало, &Конец, , ). Параметры передаются через УстановитьПараметр до выполнения запроса.
Чем ОБЪЕДИНИТЬ отличается от ОБЪЕДИНИТЬ ВСЕ?
ОБЪЕДИНИТЬ устраняет полностью совпадающие строки, что требует дополнительной сортировки на стороне СУБД. ОБЪЕДИНИТЬ ВСЕ просто складывает выборки и работает быстрее — используйте его, когда дубли между частями объединения невозможны.
Нужно ли знать SQL, чтобы писать запросы в 1С?
Не обязательно, но знание основ SQL (соединения, группировки, подзапросы) сильно помогает: логика языка запросов 1С построена на тех же принципах. Обратное тоже верно — опыт запросов в 1С облегчает изучение классического SQL.
Что важно запомнить
Язык запросов 1С — это SQL-подобный инструмент только для чтения данных, независимый от конкретной СУБД. Пишите запросы через параметры, отлаживайте в консоли, избегайте запросов в цикле и никогда не меняйте данные напрямую через SQL-сервер.