Всем привет!
Пишу отчет на СКД для УТ 10.3.
Суть проблемы в запросе: к таблице продаж я приклеиваю таблицы остатков и резервов. В параметрах последних надо накладывать отбор по номенклатуре, чтобы не получать все остатки.
Но я не пойму как это сделать в рамках СКД.
ВЫБРАТЬ
ПродажиОбороты.ДокументПродажи.Склад,
ПродажиОбороты.Номенклатура,
ЕстьNull(СУММА(ПродажиОбороты.КоличествоОборот),0) КАК Продано,
ЕстьNull(СУММА(ТоварыНаСкладахОстатки.КоличествоОстаток),0) КАК Остаток,
ЕстьNull(СУММА(ТоварыВРезервеНаСкладахОстатки.КоличествоОстаток),0) КАК Резерв
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, Период, ) КАК ПродажиОбороты
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&КонецПериода, ) КАК ТоварыНаСкладахОстатки
ПО ПродажиОбороты.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура
И ПродажиОбороты.ДокументПродажи.Склад = ТоварыНаСкладахОстатки.Склад
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(&КонецПериода, ) КАК ТоварыВРезервеНаСкладахОстатки
ПО ПродажиОбороты.Номенклатура = ТоварыВРезервеНаСкладахОстатки.Номенклатура
И ПродажиОбороты.ДокументПродажи.Склад = ТоварыВРезервеНаСкладахОстатки.Склад
СГРУППИРОВАТЬ ПО
ПродажиОбороты.Номенклатура,
ПродажиОбороты.ДокументПродажи,
ПродажиОбороты.ДокументПродажи.Склад
Показать
Я думал сначала сделать запрос по продажам, потом поместить его во временную таблицу, но ее же нельзя использовать в качестве параметра другой виртуальной таблицы.
Конечно можно и так
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&КонецПериода, Номенклатура В (Выбрать ...))
но у меня две таблицы, и в обеих делать так запрос тоже коряво.
(1) зачем делать отбор во всех таблицах? При левом соединении с соединением по номенклатуре будет отбираться только Номенклатура, которая есть в левой таблице. Отбор в данном случае вообще нет смысла делать.
(1) зачем делать отбор во всех таблицах? При левом соединении с соединением по номенклатуре будет отбираться только Номенклатура, которая есть в левой таблице. Отбор в данном случае вообще нет смысла делать.
(3) это будет, если присутствует отбор через секцию ГДЕ. Причем, если эта секция на правую таблицу, то получится выборка аналогичная внутреннему соединению.
(1) https://its.1c.ru/db/metod8dev#content:5842:hdoc:vtable_join Таблицу продаж помещаете в временную таблицу, затем еще в 2 временные таблицы выбираете данные по остальным регистрам, обязательно используя отбор Номенклатура В (Выбрать ... Из ВТПродажи). Во всех 3-х запросах индексируете поля по которым будет происходить соединение, и в четвером запросе соединяете предыдущие 3.
Это гарантровано актуально для обычных запросов. В СКД компоновщик обычно добавляет отборы сам (если совпадают имена полей). Хотя лучше всегда добавлять самому.
В любом случае сначала машина получает полную выборку а потом только ее склеивает. Я думаю лучшим вариантом будет данные упаковать во временную таблицу в пакетном запросе а потом ее использовать в качестве параметров виртуальной таблицы в остальных запросах пакета. И по тем полям по которым делаете соединение сделайте индексацию во временной таблицы.
Я думаю лучшим вариантом будет данные упаковать во временную таблицу в пакетном запросе а потом ее использовать в качестве параметров виртуальной таблицы в остальных запросах пакета.
Не поленился и получил планы запросов. С отбором из временной таблицы в параметрах виртуальных таблиц и без.
Для чистоты эксперимента в обоих запросах использовал формирование временной таблицы.
Полные планы приводить не буду. Приведу итог (статистику):
1 вариант. Без отбора в параметрах виртуальных таблиц:
(9) да, но выборка получилась небольшая и индекс не использовался в плане запроса, при чтении из временной таблицы.
Да дело даже не в индексе, количество просканированных записей показательно.