Версия для печати темы (https://pro1c.org.ua/index.php?s=b1643c754953fdf3f53e4c046541a70e&showtopic=66584)

Нажмите сюда для просмотра этой темы в обычном формате

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 _ Программирование в 1С Предприятие 8.3 _ Объединение 3-х запросов

Автор: bizisoft 09.06.21, 9:14

Здравствуйте.
1С 8.3.14.2095 Альфа-Авто 4.1.23.01

Подскажите пожалуйста возможно-ли объединить 3 запроса в один?

Запрос №1 - Получаю все аналоги для текущего товара

"ВЫБРАТЬ
        |    ГруппыАналогов.Артикул КАК Артикул,
        |    ГруппыАналогов.Производитель КАК Производитель
        |ИЗ
        |    РегистрСведений.ГруппыАналогов КАК ГруппыАналогов
        |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ГруппыАналогов КАК ГруппыАналогов1
        |        ПО ГруппыАналогов.ИдентификаторГруппы = ГруппыАналогов1.ИдентификаторГруппы
        |ГДЕ
        |    ГруппыАналогов1.Артикул = &Артикул
        |";

Результат выгружаю в СписокЗначений

Запрос №2 - Получаю из справочника ПрайсЛистыКонтрагентов список у которых стоит галочка
"ВЫБРАТЬ
        |    ПрайсЛистыКонтрагентов.Ссылка КАК Ссылка
        |ИЗ
        |    Справочник.ПрайсЛистыКонтрагентов КАК ПрайсЛистыКонтрагентов
        |ГДЕ
        |    ПрайсЛистыКонтрагентов.флКонкурент = ИСТИНА";


Результат выгружаю в СписокЗначений


Запрос №3 - Получаю товары из прайслистов контрагентов, согласно двух ранее полученных списков значений.
ВЫБРАТЬ
        |    ПрайсЛистыКонтрагентов.ПрайсЛист КАК ПрайсЛист,
        |    ПрайсЛистыКонтрагентов.Артикул КАК Артикул,
        |    ПрайсЛистыКонтрагентов.Производитель КАК Производитель,
        |    ПрайсЛистыКонтрагентов.Цена КАК Цена,
        |    ПрайсЛистыКонтрагентов.Количество КАК Количество,
        |    ПрайсЛистыКонтрагентов.Контрагент КАК Контрагент,
        |    ПрайсЛистыКонтрагентов1.Валюта КАК Валюта
        |ИЗ
        |    РегистрСведений.ПрайсЛистыКонтрагентов КАК ПрайсЛистыКонтрагентов
        |        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПрайсЛистыКонтрагентов КАК ПрайсЛистыКонтрагентов1
        |        ПО ПрайсЛистыКонтрагентов.ПрайсЛист = ПрайсЛистыКонтрагентов1.Ссылка
        |ГДЕ
        |    ПрайсЛистыКонтрагентов.Артикул В(&Артикул)
        |    И ПрайсЛистыКонтрагентов1.Ссылка В(&СпЗнКонкурентныеПрайсы)
        |    И ПрайсЛистыКонтрагентов.Производитель = &Производитель
        |
        |УПОРЯДОЧИТЬ ПО
        |    Цена";

Из результата запроса определяется позиция прайса с минимальной { ТЗ[0].Цена } и максимальной { ТЗ[ТЗ.Количество()-1].Цена } ценой и вычисляется средняя.

Я так и не смог найти, как можно в одном запросе это организовать, чтобы результаты подзапросов (Аналоги) и (Прайсы) передавались в основной запрос как списки значений.
Пробовал Вложенные запросы и временные таблицы, но связать эти три запроса так и не смог.

Можно было и оставить 3 отдельных запроса, но при переборе списка товаров в цикле, для каждого товара необходимо выполнять эти три запроса, а это наверное будет увеличивать общее время обработки списка товаров, а в дальнейшем думал попробовать вообще одним запросом обработать список товаров и вышеописанную кухню (если такое позволяют запросы).

Автор: logist 09.06.21, 10:33

Временные таблицы.

ПрайсЛистыКонтрагентов.Артикул В(ВЫБРАТЬ Т.Артикул ИЗ ВТ КАК Т)

Автор: mut 09.06.21, 11:34

условие

ПрайсЛистыКонтрагентов1.Ссылка В(&СпЗнКонкурентныеПрайсы)


исходя из текста второго запроса можно заменить на

ПрайсЛистыКонтрагентов1.Ссылка.флКонкурент


первый запрос вложить внутрь условия вместо &Артикул, потом тут же можно сгруппировать, вычислить мин/макс, среднюю

Автор: bizisoft 09.06.21, 14:08

Благодарю, LOGIST, MUT, за наколки, буду разбираться дальше.

Автор: bizisoft 14.06.21, 14:09

Все получилось.

    "ВЫБРАТЬ
    |    рсПрайсЛисты.ПрайсЛист КАК ПрайсЛист,
    |    рсПрайсЛисты.Артикул КАК Артикул,
    |    рсПрайсЛисты.Производитель КАК Производитель,
    |    рсПрайсЛисты.Цена КАК Цена,
    |    рсПрайсЛисты.Количество КАК Количество,
    |    рсПрайсЛисты.Контрагент КАК Контрагент
    |ИЗ
    |    РегистрСведений.ПрайсЛистыКонтрагентов КАК рсПрайсЛисты
    |ГДЕ
    |    рсПрайсЛисты.Артикул В
    |            (ВЫБРАТЬ
    |                Номенклатура.АртикулБезТире КАК АртикулБезТире
    |            ИЗ
    |                РегистрСведений.ГруппыАналогов КАК ГруппыАналогов
    |                    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ГруппыАналогов КАК ГруппыАналогов1
    |                    ПО
    |                        ГруппыАналогов.ИдентификаторГруппы = ГруппыАналогов1.ИдентификаторГруппы
    |                    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
    |                    ПО
    |                        ГруппыАналогов.Артикул = Номенклатура.Артикул
    |            ГДЕ
    |                ГруппыАналогов1.Артикул = &Артикул
    |                И ГруппыАналогов.Производитель = &Производитель)
    |    И рсПрайсЛисты.ПрайсЛист.Ссылка В
    |            (ВЫБРАТЬ
    |                ПрайсЛистыКонтрагентов.Ссылка КАК Ссылка
    |            ИЗ
    |                Справочник.ПрайсЛистыКонтрагентов КАК ПрайсЛистыКонтрагентов
    |            ГДЕ
    |                ПрайсЛистыКонтрагентов.флКонкурент = ИСТИНА
    |                И ПрайсЛистыКонтрагентов.Валюта = &Валюта)
    |    И рсПрайсЛисты.Производитель = &Производитель
    |
    |УПОРЯДОЧИТЬ ПО
    |    Цена";


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

Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Номенклатура.АртикулБезТире КАК АртикулБезТире
    |ИЗ
    |    РегистрСведений.ГруппыАналогов КАК ГруппыАналогов
    |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ГруппыАналогов КАК ГруппыАналогов1
    |        ПО ГруппыАналогов.ИдентификаторГруппы = ГруппыАналогов1.ИдентификаторГруппы
    |        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
    |        ПО ГруппыАналогов.Артикул = Номенклатура.Артикул
    |ГДЕ
    |    ГруппыАналогов1.Артикул = &Артикул
    |    И ГруппыАналогов.Производитель = &Производитель";

    Запрос.УстановитьПараметр("Артикул", Товар.Артикул);
    Запрос.УстановитьПараметр("Производитель", Товар.Производитель);
    Результат = Запрос.Выполнить();
    ТЗАналоги = Результат.Выгрузить();
    спАналоги = Новый СписокЗначений;
    спАналоги.Очистить();
    Если ТЗАналоги.Количество() > 0 Тогда
        //Сообщить("Выгружаем аналоги в СЗ");
        спАналоги = ТЗАналоги.ВыгрузитьКолонку("АртикулБезТире");
    Иначе
        //Сообщить("текущий Артикул в СЗ");
        спАналоги.Добавить(Товар.АртикулБезТире);
    КонецЕсли;
    
    
    
    ТЗ = Новый ТаблицаЗначений;
    ТЗ.Очистить();
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    рсПрайсЛисты.ПрайсЛист КАК ПрайсЛист,
    |    рсПрайсЛисты.Артикул КАК Артикул,
    |    рсПрайсЛисты.Производитель КАК Производитель,
    |    рсПрайсЛисты.Цена КАК Цена,
    |    рсПрайсЛисты.Количество КАК Количество,
    |    рсПрайсЛисты.Контрагент КАК Контрагент
    |ИЗ
    |    РегистрСведений.ПрайсЛистыКонтрагентов КАК рсПрайсЛисты
    |ГДЕ
    |    рсПрайсЛисты.Артикул В(&Аналоги)
    |    И рсПрайсЛисты.ПрайсЛист.Ссылка В
    |            (ВЫБРАТЬ
    |                ПрайсЛистыКонтрагентов.Ссылка КАК Ссылка
    |            ИЗ
    |                Справочник.ПрайсЛистыКонтрагентов КАК ПрайсЛистыКонтрагентов
    |            ГДЕ
    |                ПрайсЛистыКонтрагентов.флКонкурент = ИСТИНА
    |                И ПрайсЛистыКонтрагентов.Валюта = &Валюта)
    |    И рсПрайсЛисты.Производитель = &Производитель
    |
    |УПОРЯДОЧИТЬ ПО
    |    Цена";

Автор: logist 14.06.21, 20:47

Цитата(bizisoft @ 14.06.21, 15:09) *
Но был один нюанс, запрос пропускает позиции если у товара нет Аналогов, т.е. в регистре сведений ГруппыАналогов нет записи с этим товаром.

Ну вот же:
Цитата(logist @ 09.06.21, 11:33) *
Временные таблицы.

Автор: bizisoft 15.06.21, 15:41

logist @ Вчера, 21:47 * ,
Не получается, т.к. если у товара нет Аналогов, то соотвественно нет никакой записи в регистре сведений ГруппыАналогов, и поэтому ВременнаяТаблица вернет пустой ответ и итоговый результат будет пуст.

Автор: logist 15.06.21, 19:05

Цитата(bizisoft @ 15.06.21, 16:41) *
и поэтому ВременнаяТаблица вернет пустой ответ и итоговый результат будет пуст.

Сформируйте временную таблицу так, чтобы при пустой выборке регистра в результате был только ваш один параметр

Автор: bizisoft 16.06.21, 8:54

logist @ Вчера, 20:05 * ,
Не совсем понял, как это в запросе осуществить.
Попробовал так, но так не работает:

ВЫБРАТЬ
        ВЫБОР
        КОГДА
        Номенклатура.АртикулБезТире ЕСТЬ NULL
        ТОГДА  &Артикул
        ИНАЧЕ  Номенклатура.АртикулБезТире
        КОНЕЦ  КАК ГруппыАналогов
ПОМЕСТИТЬ ВТ
    ИЗ
        РегистрСведений.ГруппыАналогов КАК ГруппыАналогов
            ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ГруппыАналогов КАК ГруппыАналогов1
            ПО ГруппыАналогов.ИдентификаторГруппы = ГруппыАналогов1.ИдентификаторГруппы
            ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
            ПО ГруппыАналогов.Артикул = Номенклатура.Артикул
    ГДЕ
        ГруппыАналогов1.Артикул = &Артикул
        И ГруппыАналогов.Производитель = &Производитель


Или я не правильно понял?

Автор: logist 17.06.21, 22:30

Цитата(bizisoft @ 16.06.21, 9:54) *
Или я не правильно понял?

в общем смысл так, но реализация нет.

Где-то как-то так, но это не точно
SELECT ISNULL(IR.VC, NS.Ref) AS VC
INTO TT
FROM InformationRegister.Register1 AS IR
FULL JOIN (SELECT C.Ref AS Ref FROM    Catalog.Catalog1 AS C WHERE C.VC = &vc) AS NS
ON IR.VC = NS.Ref
WHERE IR.VC = &vc"

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua