Поиск одинаковых табличных частей

Поиск одинаковых табличных частей

Данную задачу услышал на одном собеседовании. Пользователь в обработке заполняет таблицу с колонками: Номенклатура, Характеристика, Склад. Количество строк можно ввести произвольное. Необходимо запросом отобрать все документы ПоступлениеТоваровУслуг, у которых состав табличной части Товары полностью соответствует таблице, введенной пользователем. Необходимо учесть, что строк с одинаковыми значениями может быть несколько. Порядок следования строк можно игнорировать.

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

Решение

ВЫБРАТЬ
    ТЧ.Номенклатура,
    ТЧ.Характеристика,
    ТЧ.Склад,
    &КоличествоСтрок КАК КоличествоСтрокВсего
ПОМЕСТИТЬ ТЧ
ИЗ
    &ТЧ КАК ТЧ
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ТЧ.Номенклатура,
    ТЧ.Характеристика,
    ТЧ.Склад,
    ТЧ.КоличествоСтрокВсего,
    СУММА(1) КАК ОдинаковыхСтрок
ПОМЕСТИТЬ ТЧПользователя
ИЗ
    ТЧ КАК ТЧ
СГРУППИРОВАТЬ ПО
    ТЧ.Номенклатура,
    ТЧ.Характеристика,
    ТЧ.Склад,
    ТЧ.КоличествоСтрокВсего
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ПоступлениеТоваровУслугТовары.Ссылка,
    ПоступлениеТоваровУслугТовары.Номенклатура,
    ПоступлениеТоваровУслугТовары.Характеристика,
    ПоступлениеТоваровУслугТовары.Склад,
    ВложенныйЗапрос.КоличествоСтрокВсего,
    СУММА(1) КАК ОдинаковыхСтрок
ПОМЕСТИТЬ ТЧДок
ИЗ
    Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары
        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
            ПоступлениеТоваровУслугТовары.Ссылка КАК Ссылка,
            СУММА(1) КАК КоличествоСтрокВсего
        ИЗ
            Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары
        СГРУППИРОВАТЬ ПО
            ПоступлениеТоваровУслугТовары.Ссылка) КАК ВложенныйЗапрос
        ПО ПоступлениеТоваровУслугТовары.Ссылка = ВложенныйЗапрос.Ссылка
СГРУППИРОВАТЬ ПО
    ПоступлениеТоваровУслугТовары.Ссылка,
    ПоступлениеТоваровУслугТовары.Номенклатура,
    ПоступлениеТоваровУслугТовары.Характеристика,
    ПоступлениеТоваровУслугТовары.Склад,
    ВложенныйЗапрос.КоличествоСтрокВсего
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
    ТЧДок.Ссылка
ПОМЕСТИТЬ НеПодходящиеДок
ИЗ
    ТЧДок КАК ТЧДок
        ЛЕВОЕ СОЕДИНЕНИЕ ТЧПользователя КАК ТЧПользователя
        ПО ТЧДок.Номенклатура = ТЧПользователя.Номенклатура
            И ТЧДок.Характеристика = ТЧПользователя.Характеристика
            И ТЧДок.Склад = ТЧПользователя.Склад
            И ТЧДок.ОдинаковыхСтрок = ТЧПользователя.ОдинаковыхСтрок
            И ТЧДок.КоличествоСтрокВсего = ТЧПользователя.КоличествоСтрокВсего
ГДЕ
    ТЧПользователя.Номенклатура ЕСТЬ NULL
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ПоступлениеТоваровУслуг.Ссылка
ИЗ
    Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
        ЛЕВОЕ СОЕДИНЕНИЕ НеПодходящиеДок КАК НеПодходящиеДок
        ПО ПоступлениеТоваровУслуг.Ссылка = НеПодходящиеДок.Ссылка
ГДЕ
    НеПодходящиеДок.Ссылка ЕСТЬ NULL

Рассмотрим алгоритм запроса:

  1. Во временную таблицу ТЧ помещается таблица, которую ввел пользователь. Также в отдельную колонку (КоличествоСтрокВсего) помещается при помощи параметра общее количество строк во введенной таблице. Для всех строк значение колонки будет одинаковым. Общее количество строк таблицы можно было бы посчитать и в запросе, но передача значения параметром позволила немного сократить и упростить запрос.
  2. Временная таблица ТЧ группируется и подсчитывается количество одинаковых строк. Результат помещается во временную таблицу ТЧПользователя. Данное действие необходимо для того, чтобы учесть условие задачи «учесть, что строк с одинаковыми значениями может быть несколько».
  3. Во временную таблицу ТЧДок помещаем данные о табличных частях документа. В этой же временной таблице получаем общее количество строк табличной части и количество одинаковых строк.
  4. На текущем этапе у нас подготовлены все необходимые данные. К временной таблице ТЧДок присоединяем временную таблицу ТЧПользователя. Соединение происходит по колонкам Номенклатура, Характеристика, Склад, ОдинаковыхСтрок и КоличествоСтрокВсего. После соединения отбираем те ссылки на документы, которые не полностью соответствуют временной таблице ТЧПользователя (условие на ЕСТЬ NULL), т.е. получаем НЕПОДХОДЯЩИЕ документы. Результат помещаем во временную таблицу НеПодходящиеДок.
  5. На предыдущем этапе мы получили список неподходящих документов, осталось только исключить эти документы из общей таблицы документов ПоступлениеТоваровУслуг. Осуществляем это левым соединение и проверкой на ЕСТЬ NULL.

 

Если Вы знаете другое решение задачи, пишите в комментариях.

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

Ваш e-mail не будет опубликован.