Язык запросов 1С

Условие в запросе 1С: ГДЕ, ВЫБОР и условия соединения

Условие отбора: секция ГДЕ

Основной способ наложить условие в запросе 1С — секция ГДЕ. Она фильтрует строки после выборки и соединений, оставляя только те, для которых условие истинно.

ВЫБРАТЬ
    Товары.Ссылка КАК Номенклатура,
    Товары.Цена
ИЗ
    Справочник.Номенклатура КАК Товары
ГДЕ
    Товары.Цена > 0
    И НЕ Товары.ПометкаУдаления
    И Товары.Родитель = &Группа

Несколько условий объединяются операторами И, ИЛИ, НЕ. Приоритет обычный: НЕИИЛИ. Если логика смешанная — ставьте скобки явно, иначе результат легко получить неверный:

ГДЕ
    (Товары.Цена = 0 ИЛИ Товары.Цена ЕСТЬ NULL)
    И Товары.Родитель = &Группа

Параметры и сравнение

Значение справа удобно передавать параметром через &ИмяПараметра — это защищает от ошибок типов и ускоряет запрос. Доступные операторы сравнения: =, <>, >, >=, <, <=, а также В, В ИЕРАРХИИ, МЕЖДУ, ПОДОБНО, ЕСТЬ NULL.

ЗадачаУсловие
Значение из спискаТовары.Вид В (&СписокВидов)
Вхождение в группу иерархииТовары.Ссылка В ИЕРАРХИИ (&Группа)
ДиапазонПродажи.Дата МЕЖДУ &Нач И &Кон
Поиск по части строкиТовары.Наименование ПОДОБНО &Шаблон
Проверка на NULLОстатки.Количество ЕСТЬ NULL

Условие в выборке: ВЫБОР КОГДА … ТОГДА … ИНАЧЕ

Когда условие должно не отбирать строки, а вычислять значение поля, используют оператор ВЫБОР (аналог CASE в SQL). Он возвращает разные значения в зависимости от условий:

ВЫБРАТЬ
    Продажи.Номенклатура,
    Продажи.Сумма,
    ВЫБОР
        КОГДА Продажи.Сумма >= 100000 ТОГДА "Крупная"
        КОГДА Продажи.Сумма >= 10000  ТОГДА "Средняя"
        ИНАЧЕ "Мелкая"
    КОНЕЦ КАК КатегорияПродажи
ИЗ
    РегистрНакопления.Продажи КАК Продажи

Ветки КОГДА проверяются сверху вниз — срабатывает первая истинная. Ветку ИНАЧЕ указывать не обязательно, но без неё несовпавшие строки получат NULL. Все ветки должны возвращать совместимые типы, иначе платформа приведёт их к составному типу или выдаст ошибку.

Условие по типу значения

Частый частный случай — условие «строка / число / дата» по типу реквизита составного типа. Для проверки типа есть функция ТИПЗНАЧЕНИЯ и оператор ССЫЛКА:

ВЫБОР
    КОГДА ТИПЗНАЧЕНИЯ(Движения.Регистратор) = ТИП(Документ.РеализацияТоваровУслуг)
        ТОГДА "Реализация"
    КОГДА Движения.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг
        ТОГДА "Поступление"
    ИНАЧЕ "Прочее"
КОНЕЦ

Условие в соединении: ПО

В соединениях таблиц условие задаётся в секции ПО. Важно различать: условие в ПО и условие в ГДЕ при левом соединении работают по-разному.

ВЫБРАТЬ
    Заказы.Ссылка,
    Оплаты.Сумма
ИЗ
    Документ.ЗаказКлиента КАК Заказы
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Оплаты КАК Оплаты
    ПО Оплаты.Заказ = Заказы.Ссылка
        И Оплаты.Дата >= &НачалоПериода

Здесь фильтр по дате стоит в ПО: заказы без оплат останутся в результате (с NULL в сумме). Если тот же фильтр перенести в ГДЕ, строки с NULL отсеются, и левое соединение фактически превратится во внутреннее — типичная скрытая ошибка.

Частые ошибки в условиях запроса

  • Сравнение с NULL через «=». Условие Поле = NULL всегда ложно. Используйте Поле ЕСТЬ NULL или ЕСТЬNULL(Поле, 0).
  • Фильтр в ГДЕ вместо ПО при левом соединении. Отсекает нужные строки (см. пример выше).
  • Пустая строка ≠ NULL. Для реквизитов-строк проверяйте и то, и другое: Поле = "" ИЛИ Поле ЕСТЬ NULL.
  • Условие по несуществующему реквизиту. Опечатка в имени поля или объекта — и запрос падает уже при выполнении. Проверяйте имена по метаданным именно вашей конфигурации.
  • ПОДОБНО без экранирования спецсимволов. Символы % и _ в шаблоне трактуются как маска. Для буквального поиска используйте СПЕЦСИМВОЛ.

Кратко

  • ГДЕ — отбор строк результата.
  • ВЫБОР КОГДА … ТОГДА … ИНАЧЕ … КОНЕЦ — условие для вычисления значения поля.
  • ПО — условие соединения таблиц; в левом соединении не переносите его в ГДЕ.
  • Для NULL — ЕСТЬ NULL и ЕСТЬNULL(), а не = NULL.