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

Доброго дня, коллеги!

Помните, мы уже разбирали вопрос, где наша внимательная слушательница решила самостоятельно исследовать метаданные конфигурации, в результате чего у нее появились интересные вопросы?

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

Вопрос

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

● ГДЕ ТИПЗНАЧЕНИЯ(ТоварныеЗапасы.Регистратор) = ТИП(Документ.РасходТовара)
● ГДЕ ТоварныеЗапасы.Регистратор ССЫЛКА Документ.РасходТовара
● ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РасходТовара)

А какой из вариантов оптимален с методической точки зрения? Предположительно ВЫРАЗИТЬ исполнится до отбора данных. Так ли это?

Ответ

Можно использовать первые два варианта – оператор ССЫЛКА или функцию ТИПЗНАЧЕНИЯ.
При помощи оператора ВЫРАЗИТЬ можно привести значение только к одному типу:

ВЫРАЗИТЬ Поле КАК Тип

Т.е. сам по себе он не выполняет отбор. Нужно дополнительно в секции ГДЕ установить отбор.


Оператор ССЫЛКА не убирает лишние неявные соединения (это можно проверить при помощи просмотра плана запроса в консоли), а накладывает отбор по типу. А ВЫРАЗИТЬ явно говорит, что поле будет иметь не составной тип, а одну конкретную ссылку, поэтому не будет лишних соединений.

У оператора ССЫЛКА есть особенность.


Пусть используется следующий фрагмент запроса:

&ЦеноваяГруппа ССЫЛКА Справочник.ЦеновыеГруппы


Если в качестве значения параметра ЦеноваяГруппа установить, например, ссылку на справочник «Номенклатура», система выдаст ошибку:


Несовместимые типы “ССЫЛКА”
& ЦеноваяГруппа <<?>>ССЫЛКА Справочник.ЦеновыеГруппы


При работе с реквизитами составного типа тоже может возникать такая же ошибка. Например, документ «РеализацияТоваровУслуг» не входит в составной тип реквизита ДокументОснование документа «Авансовый Отчет». При выполнении запроса будет ошибка:

ВЫБРАТЬ
    АвансовыйОтчет.ДокументОснование ССЫЛКА Документ.РеализацияТоваровУслуг
 ИЗ Документ.АвансовыйОтчет КАК АвансовыйОтчет

Причем конструктор запроса даже не будет открываться. ТИПЗНАЧЕНИЯ при этом отработает корректно.


Фирма 1С поясняет это следующим образом:
«Язык запросов выдает эту ошибку, если в типе проверяемого выражения отсутствует ссылка на проверяемую таблицу

Вот такую особенность нужно учитывать при разработке запросов.

Кстати, завтра мы вновь вернемся к запросам. Обещаем, будет интересно!

P.S.

Понимать, как работают запросы и уметь их строить - обязательный навык для всех, кто дорабатывает и внедряет 1С.

После курса Вы сможете:

  • Строить сложные запросы с несколькими источниками данных
  • Уверенно задействовать вложенные запросы и временные таблицы
  • Использовать встроенный язык для обработки результатов запроса
  • Учитывать особенности соединений и объединений нескольких таблиц.
  • Разрабатывать запросы на уровне задач Аттестации 1С:Специалист по платформе.
Программа, стоимость, условия и регистрация в группу: «Запросы в 1С 8.3, Базовый курс (с нуля до уровня Специалист по платформе)» Для всех, кто внедряет и дорабатывает 1С.

Комментарии / обсуждение (6):

    • Василий Ханевич

      Добрый день!
      Можно вот так:

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

        Добрый день, на ИТС написано “Не следует использовать ИЛИ в секции ГДЕ запроса. Это может привести к тому, что СУБД не сможет использовать индексы таблиц и будет выполнять сканирование, что увеличит время работы запроса и вероятность возникновения блокировок”. К данному случаю это не относится?

        • Василий Ханевич

          Добрый день!
          Да, есть такая рекомендация. И запрос из предыдущего комментария можно переписать с использованием двух объединений вместо оператора ИЛИ.
          В общем случае нужно проверить, какие планы запросов на уровне СУБД получаются для каждого из запроса. И выбрать из двух запросов тот, который является оптимальным.

  1. Олег Петухов

    ни разу не приходилось в запросах указывать документ, который не входит в составной тип данных.
    обычно ССЫЛКА использую, когда надо отсечь ненужные типы данных в составной типе данных (например получить записи из регистра только определЁнного документа, поэтому в секции ГДЕ пишу Регистратор ССЫЛКА Документ.ххххх).

    а вот то, что ССЫЛКА не убирает ненужные соединения – это была полезная инфа!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Вход на сайт

Зарегистрироваться

Подтверждение регистрации будет отправлено на указанный e-mail.

Я подтверждаю, что ознакомлен(а) с Пользовательским соглашением, принимаю его условия и даю свое согласие на обработку моих персональных данных.

Восстановить доступ

E-mail или логин

Ссылка на создание нового пароля будет отправлена на указанный e-mail.