Оператор ВЫБРАТЬ КОГДА (или SELECT CASE в англоязычной терминологии) — один из самых мощных инструментов языка запросов 1С:Предприятие. Он позволяет реализовывать условную логику прямо в SQL-подобных конструкциях, избегая громоздких объединений таблиц или пост-обработки результатов на стороне клиента. Однако многие разработчики используют его неэффективно: либо перегружают запросы вложенными условиями, либо упускают возможности оптимизации.

В этой статье мы разберём синтаксис оператора на практических примерах, покажем, как комбинировать его с другими конструкциями (МЕЖДУ, В, ПОДОБНО), а также раскроем ключевые ошибки, которые приводят к падению производительности запросов в 1С. Особое внимание уделим нюансам работы с датами, перечислениями и динамическими условиями.

Если вы только начинаете осваивать язык запросов 1С, этот материал поможет избежать типичных подводных камней. Опытные разработчики найдут здесь нетривиальные кейсы применения ВЫБРАТЬ КОГДА, которые редко освещаются в стандартной документации.

1. Базовый синтаксис оператора ВЫБРАТЬ КОГДА

Конструкция ВЫБРАТЬ КОГДА работает по принципу switch-case: последовательно проверяет условия и возвращает результат первого совпадения. Если ни одно условие не выполнено, используется значение после ИНАЧЕ (аналог DEFAULT в SQL).

Общий вид:

ВЫБРАТЬ

ВЫБОР

КОГДА <Условие1> ТОГДА <Результат1>

КОГДА <Условие2> ТОГДА <Результат2>

...

ИНАЧЕ <РезультатПоУмолчанию>

КОНЕЦ КАК ПолеРезультата

ИЗ ...

Пример с классификацией клиентов по сумме заказов:

ВЫБРАТЬ

Клиенты.Наименование КАК Клиент,

ВЫБОР

КОГДА СУММА(Заказы.СуммаДокумента) > 1000000 ТОГДА "VIP"

КОГДА СУММА(Заказы.СуммаДокумента) > 100000 ТОГДА "Премиум"

ИНАЧЕ "Стандарт"

КОНЕЦ КАК КатегорияКлиента

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Заказы КАК Заказы

ПО Клиенты.Ссылка = Заказы.Клиент

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

Клиенты.Наименование

Важно: условия проверяются последовательно, поэтому более строгие критерии должны идти первыми. Например, если поменять местами условия в примере выше, все клиенты с суммой заказов >1 млн попадут в категорию "Премиум", так как первое условие (>100000) сработает раньше.

⚠️ Внимание: В версиях 1С ниже 8.3.10 оператор ВЫБОР КОГДА не поддерживался в подзапросах. Если вам нужно использовать его в сложных конструкциях, убедитесь в актуальности платформы.

2. Примеры использования с разными типами данных

Оператор ВЫБРАТЬ КОГДА универсален и работает с любыми типами полей: числами, строками, датами, булевыми значениями и даже ссылками. Рассмотрим ключевые сценарии.

2.1. Работа с датами

Частая задача — классификация документов по периодам (например, "текущий месяц", "прошлый квартал"). Здесь удобно использовать функции НАЧАЛОПЕРИОДА() и КОНЕЦПЕРИОДА():

ВЫБРАТЬ

ВЫБОР

КОГДА Документы.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&ТекущаяДата, "Месяц")

И КОНЕЦПЕРИОДА(&ТекущаяДата, "Месяц")

ТОГДА "Текущий месяц"

КОГДА Документы.Дата >= НАЧАЛОПЕРИОДА(&ТекущаяДата, "Квартал")

ТОГДА "Текущий квартал"

ИНАЧЕ "Архив"

КОНЕЦ КАК Период

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

2.2. Обработка перечислений

Если в базе есть справочник с фиксированным набором значений (например, "СтатусЗаказа"), можно заменить ссылки на читаемые строки:

ВЫБРАТЬ

ВЫБОР

КОГДА Заказы.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказов.Новый)

ТОГДА "Новый заказ"

КОГДА Заказы.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказов.Оплачен)

ТОГДА "Оплачен"

КОГДА Заказы.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказов.Отгружен)

ТОГДА "Отгружен"

КОНЕЦ КАК СтатусТекстом

ИЗ Документ.ЗаказКлиента КАК Заказы

2.3. Динамические условия с параметрами

Параметры запроса (&Параметр) можно использовать прямо в условиях КОГДА. Например, фильтрация товаров по остаткам с учётом минимального порога:

ВЫБРАТЬ

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

ВЫБОР

КОГДА ОстаткиТоваров.КоличествоОстаток > &МаксимальныйОстаток

ТОГДА "Избыток"

КОГДА ОстаткиТоваров.КоличествоОстаток < &МинимальныйОстаток

ТОГДА "Дефицит"

ИНАЧЕ "Норма"

КОНЕЦ КАК СостояниеОстатка

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров КАК ОстаткиТоваров

ПО Номенклатура.Ссылка = ОстаткиТоваров.Номенклатура

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

3. Комбинация с другими операторами: МЕЖДУ, В, ПОДОБНО

Оператор ВЫБРАТЬ КОГДА можно комбинировать с другими конструкциями языка запросов для создания сложной логики. Это особенно полезно при работе с диапазонами значений, списками или шаблонами строк.

3.1. Оператор МЕЖДУ для числовых диапазонов

Классический пример — распределение клиентов по сегментам по сумме покупок:

ВЫБРАТЬ

Клиенты.Наименование КАК Клиент,

ВЫБОР

КОГДА СУММА(Продажи.Сумма) МЕЖДУ 100000 И 500000

ТОГДА "Средний сегмент"

КОГДА СУММА(Продажи.Сумма) > 500000

ТОГДА "Крупный клиент"

ИНАЧЕ "Мелкий клиент"

КОНЕЦ КАК Сегмент

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Продажи

ПО Клиенты.Ссылка = Продажи.Клиент

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

Клиенты.Наименование

3.2. Оператор В для проверки принадлежности списку

Если нужно проверить, входит ли значение в фиксированный набор, удобно использовать В:

ВЫБРАТЬ

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

ВЫБОР

КОГДА Номенклатура.Группа В (&СписокПремиальныхГрупп)

ТОГДА "Премиальный товар"

КОГДА Номенклатура.Группа = ЗНАЧЕНИЕ(Справочник.ГруппыНоменклатуры.Уцененные)

ТОГДА "Уцененный товар"

КОНЕЦ КАК ТипТовара

ИЗ

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

Где &СписокПремиальныхГрупп — массив ссылок на группы номенклатуры, переданный в запрос как параметр.

3.3. Оператор ПОДОБНО для строковых шаблонов

Для фильтрации по частичному совпадению строк (например, артикулов или наименований) подходит ПОДОБНО:

ВЫБРАТЬ

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

ВЫБОР

КОГДА Номенклатура.Артикул ПОДОБНО "АРТ-%"

ТОГДА "Старая серия"

КОГДА Номенклатура.Артикул ПОДОБНО "NEW-%"

ТОГДА "Новая серия"

КОНЕЦ КАК СерияТовара

ИЗ

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

Оператор Пример использования Когда применять
МЕЖДУ КОГДА Сумма МЕЖДУ 1000 И 5000 Для числовых или временных диапазонов
В КОГДА Группа В (&СписокГрупп) Проверка принадлежности к набору значений
ПОДОБНО КОГДА Артикул ПОДОБНО "ABC-%" Поиск по шаблону (подстрокам, префиксам)
И/ИЛИ КОГДА (Цена > 1000) И (Склад = &ОсновнойСклад) Сложные составные условия
⚠️ Внимание: Оператор ПОДОБНО может значительно замедлить запрос, если применяется к неиндексированным полям. Для крупных таблиц (например, Документ.ЗаказКлиента) лучше использовать индексированные поля или предварительную фильтрацию.
ВЫБРАТЬ

ВЫБОР

КОГДА (Условие1 И Условие2) ИЛИ Условие3 ТОГДА ...

КОНЕЦ КАК Результат

ИЗ (

ВЫБРАТЬ

Условие1 КАК Условие1,

Условие2 КАК Условие2,

Условие3 КАК Условие3

ИЗ ...

) КАК Подзапрос

-->

4. Типичные ошибки и как их избежать

Несмотря на кажущуюся простоту, оператор ВЫБРАТЬ КОГДА часто становится источником проблем — от логических ошибок до падения производительности. Вот наиболее распространённые промахи:

4.1. Отсутствие условия ИНАЧЕ

Если не указать ИНАЧЕ, то для записей, не попадающих ни под одно условие, будет возвращено NULL. Это может привести к неожиданным результатам при дальнейшей обработке:

-- Плохо: нет обработки для остальных случаев

ВЫБОР

КОГДА Статус = "Оплачен" ТОГДА 1

КОГДА Статус = "Отменен" ТОГДА 0

КОНЕЦ КАК СтатусЧислом

Лучше явно указывать значение по умолчанию:

-- Хорошо: все случаи обработаны

ВЫБОР

КОГДА Статус = "Оплачен" ТОГДА 1

КОГДА Статус = "Отменен" ТОГДА 0

ИНАЧЕ -1

КОНЕЦ КАК СтатусЧислом

4.2. Избыточные условия

Если условия перекрывают друг друга, это не только усложняет поддержку кода, но и может приводить к неверным результатам. Например:

-- Плохо: второе условие избыточно

ВЫБОР

КОГДА Сумма > 100000 ТОГДА "VIP"

КОГДА Сумма > 50000 ТОГДА "Премиум" -- Никогда не сработает!

ИНАЧЕ "Стандарт"

КОНЕЦ

Упорядочивайте условия от наиболее специфичных к наименее специфичным.

4.3. Использование функций в условиях

Вычисления внутри КОГДА (например, ЛЕВ(Строка, 3)) выполняются для каждой строки, что тормозит запрос. Лучше вынести их в отдельные поля:

-- Оптимально: вычисление один раз

ВЫБРАТЬ

ЛЕВ(Номенклатура.Артикул, 3) КАК ПрефиксАртикула,

ВЫБОР

КОГДА ПрефиксАртикула = "ABC" ТОГДА "Серия A"

КОГДА ПрефиксАртикула = "XYZ" ТОГДА "Серия X"

КОНЕЦ КАК Серия

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

  • 🔍 Пропущенное ИНАЧЕ: Всегда обрабатывайте все возможные случаи, даже если "их не должно быть".
  • 📉 Избыточные условия: Проверяйте, не перекрываются ли ваши КОГДА друг с другом.
  • 🐢 Функции в условиях: Выносите вычисления за пределы ВЫБОР, чтобы избежать повторных расчётов.
  • 🗑️ Нечитаемые вложенности: Если внутри КОГДА больше 3-х уровней вложенных условий, разбейте запрос на части.
Почему запрос с ВЫБРАТЬ КОГДА может работать медленно?

Если в условиях используются неиндексированные поля (например, строковые функции или вычисления), СУБД не может оптимизировать выполнение через индексы. В результате запрос сканирует всю таблицу (table scan), а не использует быстрый поиск по индексу (index seek). Особенно критично это для крупных таблиц (например, Документ.ПоступлениеТоваров с миллионами записей).

5. Оптимизация запросов с ВЫБРАТЬ КОГДА

Запросы с большим количеством условий КОГДА могут становиться "бутылочным горлышком" производительности. Вот ключевые приёмы оптимизации:

5.1. Использование индексированных полей

Убедитесь, что поля, используемые в условиях КОГДА, имеют индексы в базе данных. Например, если вы фильтруете по полю Дата, оно должно быть проиндексировано. Проверить индексы можно через консоль администратора 1С или SQL-профайлер.

5.2. Замена на соединения (JOIN)

Если условия КОГДА проверяют принадлежность к справочникам, иногда эффективнее использовать соединения:

-- Вместо:

ВЫБРАТЬ

ВЫБОР

КОГДА Товары.Категория = &Категория1 ТОГДА "Категория 1"

КОГДА Товары.Категория = &Категория2 ТОГДА "Категория 2"

КОНЕЦ КАК КатегорияТекстом

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

-- Лучше:

ВЫБРАТЬ

Товары.Наименование,

Категории.Наименование КАК КатегорияТекстом

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.КатегорииТоваров КАК Категории

ПО Товары.Категория = Категории.Ссылка

ГДЕ Категории.Ссылка В (&СписокКатегорий)

5.3. Разделение сложных запросов

Если запрос содержит более 5-7 условий КОГДА, рассмотрите возможность разбить его на несколько простых с использованием временных таблиц:

ВЫБРАТЬ

Товары.Ссылка КАК Ссылка,

ВЫБОР

КОГДА Остатки.Количество > 100 ТОГДА "Много"

ИНАЧЕ "Мало"

КОНЕЦ КАК Наличие

ПОМЕСТИТЬ ВТОстатки

ИЗ ...

;

ВЫБРАТЬ

Товары.Наименование,

Остатки.Наличие,

ВЫБОР

КОГДА Товары.Цена > 10000 ТОГДА "Дорогой"

ИНАЧЕ "Дешевый"

КОНЕЦ КАК ЦеноваяКатегория

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ ВТОстатки КАК Остатки

ПО Товары.Ссылка = Остатки.Ссылка

5.4. Кеширование повторяющихся вычислений

Если одно и то же выражение используется в нескольких условиях, вынесите его в отдельное поле:

ВЫБРАТЬ

СУММА(Продажи.Сумма) КАК ОбщаяСумма,

ВЫБОР

КОГДА ОбщаяСумма > 1000000 ТОГДА "VIP"

КОГДА ОбщаяСумма > 100000 ТОГДА "Премиум"

КОНЕЦ КАК Категория

ИЗ ...

Поля в условиях имеют индексы|Сложные вычисления вынесены в отдельные поля|Количество условий КОГДА не превышает 5-7|Использованы соединения вместо вложенных ВЫБОРов|Проверено выполнение через EXPLAIN (в SQL-профайлере)

-->

💡

Самая частая причина медленных запросов с ВЫБРАТЬ КОГДА — отсутствие индексов на полях, используемых в условиях. Всегда проверяйте план выполнения запроса в SQL-профайлере!

6. Практический пример: сложный отчёт с классификацией данных

Рассмотрим реальный кейс: нужно построить отчёт по продажам с классификацией товаров по нескольким критериям:

  1. По сумме продаж (топ/середняк/аутсайдер).
  2. По динамике продаж (растущий/падающий/стабильный).
  3. По категории товара (премиум/стандарт/эконом).

Исходный запрос с вложенными ВЫБОР:

ВЫБРАТЬ

Товары.Наименование КАК Товар,

СУММА(Продажи.Количество) КАК ПроданоШтук,

СУММА(Продажи.Сумма) КАК Выручка,

-- Классификация по сумме продаж

ВЫБОР

КОГДА СУММА(Продажи.Сумма) > 500000 ТОГДА "Топ"

КОГДА СУММА(Продажи.Сумма) > 50000 ТОГДА "Средний"

ИНАЧЕ "Аутсайдер"

КОНЕЦ КАК СегментПоВыручке,

-- Классификация по динамике (сравнение с прошлым месяцем)

ВЫБОР

КОГДА СУММА(Продажи.Количество) > ЛАГ(СУММА(Продажи.Количество), 1) ОКНО (ПАРТИЦИЯ ПО Товары.Ссылка УПОРЯДОЧИТЬ ПО Продажи.Дата)

ТОГДА "Растущий"

КОГДА СУММА(Продажи.Количество) < ЛАГ(СУММА(Продажи.Количество), 1) ОКНО (ПАРТИЦИЯ ПО Товары.Ссылка УПОРЯДОЧИТЬ ПО Продажи.Дата)

ТОГДА "Падающий"

ИНАЧЕ "Стабильный"

КОНЕЦ КАК ДинамикаПродаж,

-- Классификация по категории товара

ВЫБОР

КОГДА Товары.Категория = ЗНАЧЕНИЕ(Справочник.КатегорииТоваров.Премиум)

ТОГДА "Премиум"

КОГДА Товары.Категория = ЗНАЧЕНИЕ(Справочник.КатегорииТоваров.Эконом)

ТОГДА "Эконом"

ИНАЧЕ "Стандарт"

КОНЕЦ КАК КатегорияТовара

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Продажи

ПО Товары.Ссылка = Продажи.Товар

ГДЕ

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

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

Товары.Наименование,

Товары.Категория

Оптимизированная версия (с предварительным расчётом динамики):

-- Шаг 1: расчёт продаж по месяцам

ВЫБРАТЬ

Товары.Ссылка КАК Товар,

НАЧАЛОПЕРИОДА(Продажи.Дата, "Месяц") КАК Месяц,

СУММА(Продажи.Количество) КАК ПроданоШтук

ПОМЕСТИТЬ ВТПродажиПоМесяцам

ИЗ ...

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

СГРУППИРОВАТЬ ПО Товары.Ссылка, НАЧАЛОПЕРИОДА(Продажи.Дата, "Месяц")

;

-- Шаг 2: расчёт динамики

ВЫБРАТЬ

Товар,

Месяц,

ПроданоШтук,

ЛАГ(ПроданоШтук, 1) ОКНО (ПАРТИЦИЯ ПО Товар УПОРЯДОЧИТЬ ПО Месяц) КАК ПроданоПредыдущийМесяц

ПОМЕСТИТЬ ВТДинамика

ИЗ ВТПродажиПоМесяцам

;

-- Шаг 3: финальный отчёт

ВЫБРАТЬ

Товары.Наименование КАК Товар,

СУММА(Продажи.Сумма) КАК Выручка,

ВЫБОР

КОГДА СУММА(Продажи.Сумма) > 500000 ТОГДА "Топ"

ИНАЧЕ "Прочие"

КОНЕЦ КАК СегментПоВыручке,

МАКСИМУМ(

ВЫБОР

КОГДА Динамика.ПроданоШтук > Динамика.ПроданоПредыдущийМесяц ТОГДА "Растущий"

КОГДА Динамика.ПроданоШтук < Динамика.ПроданоПредыдущийМесяц ТОГДА "Падающий"

ИНАЧЕ "Стабильный"

КОНЕЦ

) КАК ДинамикаПродаж

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Продажи

ПО Товары.Ссылка = Продажи.Товар

ЛЕВОЕ СОЕДИНЕНИЕ ВТДинамика КАК Динамика

ПО Товары.Ссылка = Динамика.Товар

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

СГРУППИРОВАТЬ ПО Товары.Наименование

Такой подход уменьшает нагрузку на СУБД за счёт:

  1. Разделения сложной логики на простые шаги.