В типовых конфигурациях, таких как 1С:Управление торговлей 11, ERP 2 или Комплексная автоматизация 2, характеристики номенклатуры и дополнительные реквизиты хранятся по модели EAV (Entity-Attribute-Value). Это означает, что свойства не являются колонками таблицы, а хранятся в виде отдельных строк в связанных таблицах (например, в табличной части или регистре сведений). В данной статье мы проанализируем, как правильно написать запрос для поиска объектов, которые одновременно обладают всем набором заданных свойств.
Рассмотрим ситуацию: нам необходимо найти характеристику, у которой «Цвет» — «Красный» И «Размер» — «42». Если мы просто напишем условие ГДЕ, запрос вернет пустой результат или некорректные данные, так как в одной строке таблицы свойств не может одновременно находиться и цвет, и размер. Каждое свойство — это отдельная запись.
Для решения этой задачи в реляционных базах данных используется операция, называемая реляционным делением. Нам нужно отобрать те характеристики, для которых количество совпавших свойств равно количеству свойств в нашем фильтре.
Разберем наиболее эффективный алгоритм решения «одним запросом». Этот метод основан на подсчете количества уникальных совпадений для каждой характеристики. Проанализируем шаги реализации:
Свойство и Значение.ИМЕЮЩИЕ установим условие, что количество найденных свойств должно быть равно общему количеству свойств в фильтре.Посмотрим на пример реализации такого запроса:
// Предположим, ПараметрыОтбора - это ТаблицаЗначений с колонками Свойство и Значение
// &КоличествоСвойств - число строк в этой таблице
ВЫБРАТЬ
ДопРеквизиты.Ссылка КАК Характеристика
ИЗ
Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ДопРеквизиты
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Фильтр КАК Фильтр
ПО ДопРеквизиты.Свойство = Фильтр.Свойство
И ДопРеквизиты.Значение = Фильтр.Значение
ГРУППИРОВАТЬ ПО
ДопРеквизиты.Ссылка
ИМЕЮЩИЕ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ДопРеквизиты.Свойство) = &КоличествоСвойств
Рассмотрим альтернативный вариант, который предложили участники обсуждения. Этот метод может быть полезен, если необходимо реализовать сложную логику отбора «от обратного».
Алгоритм действий следующий:
ВТ_Предварительная.ВТ_Исключения.ВТ_Предварительная, которых нет в ВТ_Исключения.Этот способ более трудозатратный для сервера БД, однако он наглядно показывает логику отсеивания неподходящих вариантов. Тем не менее, для промышленной разработки рекомендуется использовать Метод 1.
Проанализируем нюанс, который часто становится причиной ошибок (как это случилось в обсуждении на форуме). В 1С:Управление торговлей 11 свойства могут храниться не только в справочнике ХарактеристикиНоменклатуры, но и наследоваться от владельца (Номенклатуры) или определяться настройками вида номенклатуры.
Для корректного решения задачи выясним следующие моменты:
ИМЕЮЩИЕ нужно добавить проверку на общее количество записей в таблице свойств данной характеристики.КомпоновщикНастроек и систему компоновки данных. СКД автоматически генерирует текст запроса с нужным количеством соединений при динамическом добавлении фильтров пользователем.Как показала практика обсуждения, даже верный на первый взгляд код может выдать пустой список. Разберем основные причины:
ЗначенияСвойствОбъектов), соединение не сработает.ВТ_Фильтр обязательно нужно проиндексировать по полям Свойство и Значение для быстродействия.Используя представленные методы, вы сможете реализовать гибкий и производительный поиск объектов по любым наборам дополнительных свойств в конфигурациях на платформе 1С:Предприятие 8.3.