Продвинутый курс. Домашнее задание №9
Очередное задание по 1-му блоку продвинутого курса.
Для выполнения рекомендуется изучить следующие главы 1-го блока.
Глава 8. Оптимизация производительности прикладных решений.
Глава 9. Оптимизация производительности при работе с БД.*
* – эта тема еще не выложена. Надеемся, что файлы с защитой появятся 16 декабря.
В этой же теме необходимо написать отчет о выполнении задания.
К сожалению, у Вас недостаточно прав для просмотра этой записи. Если Вы еще не залогинены на сайте — залогиньтесь. Если Вы оплачивали курс, у Вас активирован токен доступа, Вы залогинены, но Вы видите эту запись — напишите нам на e-mail поддержки.
Выполнил.
1. Внутреннее соединение без NULL
2.
<code>
Запрос = Новый Запрос(
“ВЫБРАТЬ
| ЕСТЬNULL(ПродажиОбороты.Номенклатура, ОстаткиТоваровОстатки.Номенклатура) КАК Номенклатура,
| СУММА(ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0)) КАК КоличествоОборот,
| СУММА(ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0)) КАК КоличествоОстаток,
| ВЫБОР
| КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100
| ТОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0)
| ИНАЧЕ ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0)
| КОНЕЦ КАК ПолеСортировки
|ИЗ
| РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
| ПО ПродажиОбороты.Номенклатура = ОстаткиТоваровОстатки.Номенклатура
|
|СГРУППИРОВАТЬ ПО
| ЕСТЬNULL(ПродажиОбороты.Номенклатура, ОстаткиТоваровОстатки.Номенклатура),
| ВЫБОР
| КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100
| ТОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0)
| ИНАЧЕ ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0)
| КОНЕЦ
|
|УПОРЯДОЧИТЬ ПО
| ПолеСортировки УБЫВ”)
</code>
3.
<code>
Запрос = Новый Запрос(
“ВЫБРАТЬ
| СпрНоменклатура.Ссылка КАК Номенклатура,
| ЕСТЬNULL(ЦеныНоменклатуры.Цена, 0) КАК Цена
|ПОМЕСТИТЬ ВТНоменклатура
|ИЗ
| Справочник.Номенклатура КАК СпрНоменклатура
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
| ПО СпрНоменклатура.Ссылка = ЦеныНоменклатуры.Номенклатура
|;
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| ПоступлениеТоваровИУслугТовары.Ссылка.Контрагент,
| ПоступлениеТоваровИУслугТовары.Номенклатура
|ПОМЕСТИТЬ ВТПоставщики
|ИЗ
| Документ.ПоступлениеТоваровИУслуг.Товары КАК ПоступлениеТоваровИУслугТовары
|ГДЕ
| ПоступлениеТоваровИУслугТовары.Номенклатура В
| (ВЫБРАТЬ
| ВТ.Номенклатура
| ИЗ
| ВТНоменклатура КАК ВТ)
|;
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТНоменклатура.Номенклатура КАК Номенклатура,
| ВТНоменклатура.Цена,
| ВТПоставщики.Контрагент
|ИЗ
| ВТНоменклатура КАК ВТНоменклатура
| ЛЕВОЕ СОЕДИНЕНИЕ ВТПоставщики КАК ВТПоставщики
| ПО ВТНоменклатура.Номенклатура = ВТПоставщики.Номенклатура”)
</code>
Задание выполнил.
Первая оптимизация – внутреннее соединение, проверку на null убрал вообще
По второму заданию сделал дополнительно два поля – ПорядокПродажи и ПорядокОстатки, которые заполняю при обходе запроса оператором Выбор. Потом упорядочиваю ПорядокПродажи УБЫВ, ПорядокОстатки УБЫВ
По третьему заданию переделал полностью. Во временную таблицу остатки. Затем ее соединил с оборотным регистром Закупки и Ценами.
1.
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток,
ПродажиОбороты.КоличествоОборот
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ПО ПродажиОбороты.Номенклатура = ОстаткиТоваровОстатки.Номенклатура
2.
ВЫБРАТЬ
ЕСТЬNULL(ОстаткиТоваровОстатки.Номенклатура, ПродажиОбороты.Номенклатура) КАК Номенклатурв,
ОстаткиТоваровОстатки.КоличествоОстаток,
ПродажиОбороты.КоличествоОборот,
ВЫБОР
КОГДА ПродажиОбороты.КоличествоОборот > 1
ТОГДА ПродажиОбороты.КоличествоОборот
ИНАЧЕ ОстаткиТоваровОстатки.КоличествоОстаток
КОНЕЦ КАК Порядок
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ПО ПродажиОбороты.Номенклатура = ОстаткиТоваровОстатки.Номенклатура
УПОРЯДОЧИТЬ ПО
Порядок УБЫВ
3. Проще написать занова, чем оптимизировать..
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура КАК Номенклатура
ПОМЕСТИТЬ Остатки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура,
ЦеныНоменклатурыСрезПоследних.Цена
ПОМЕСТИТЬ Цены
ИЗ
РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
,
Номенклатура В
(ВЫБРАТЬ
Остатки.Номенклатура
ИЗ
Остатки КАК Остатки)) КАК ЦеныНоменклатурыСрезПоследних
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
ОстаткиТоваровОбороты.Регистратор.Контрагент КАК Контрагент,
ОстаткиТоваровОбороты.Номенклатура,
Цены.Цена
ИЗ
РегистрНакопления.ОстаткиТоваров.Обороты(
,
,
Регистратор,
Номенклатура В
(ВЫБРАТЬ
Остатки.Номенклатура
ИЗ
Остатки КАК Остатки)) КАК ОстаткиТоваровОбороты
ЛЕВОЕ СОЕДИНЕНИЕ Цены КАК Цены
ПО ОстаткиТоваровОбороты.Номенклатура = Цены.Номенклатура
ГДЕ
ОстаткиТоваровОбороты.Регистратор ССЫЛКА Документ.ПоступлениеТоваровИУслуг
Задание выполнено, в целом без затруднений.
Домашнее задание выполнено.
Задача №1
Можно было обойтись изменением левого соединения на внутреннее и удаление лишней проверки на null.
Решил оптимизировать запрос и поместить данные по регистрам во ВТ и в итоговом запросе уже связать их.
Получился вот такой простенький запрос:
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура КАК Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток
ПОМЕСТИТЬ ВТОстатки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ ВТПродажи
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ГДЕ
ПродажиОбороты.КоличествоОборот > 0
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТОстатки.Номенклатура,
ВТОстатки.КоличествоОстаток,
ВТПродажи.КоличествоОборот
ИЗ
ВТОстатки КАК ВТОстатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТПродажи КАК ВТПродажи
ПО ВТОстатки.Номенклатура = ВТПродажи.Номенклатура
Задача №2
Берем запрос из 1 задачи с добавленным параметром виртуальной таблицы «Остатки» и добавляем туда поле сортировки:
ВЫБОР
КОГДА ВТПродажи.КоличествоОборот > 100
ТОГДА ВТПродажи.КоличествоОборот
ИНАЧЕ 0
КОНЕЦ КАК ПолеСортировки
И настраиваем сортировку:
УПОРЯДОЧИТЬ ПО
ПолеСортировки УБЫВ,
КоличествоОстаток УБЫВ
Задача №3
Изначально опираемся на номенклатуру, которая есть в остатке. Для этого ее помещаем во ВТ и индексируем эту ВТ по полю Номенклатура. Поставщика берем из оборотов регистра накопления «ОстаткиТоваров», где ОстаткиТоваровОбороты.КоличествоОборот > 0 и Номенклатура в ВТ. Аналогично с ценами.
Получившийся запрос:
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура КАК Номенклатура
ПОМЕСТИТЬ ВТОстатки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
ОстаткиТоваровОбороты.Номенклатура,
ВЫРАЗИТЬ(ОстаткиТоваровОбороты.Регистратор КАК Документ.ПоступлениеТоваровИУслуг).Контрагент КАК Поставщик,
ЦеныНоменклатурыСрезПоследних.Цена
ИЗ
РегистрНакопления.ОстаткиТоваров.Обороты(
,
,
Регистратор,
Номенклатура В
(ВЫБРАТЬ
ВТОстатки.Номенклатура
ИЗ
ВТОстатки КАК ВТОстатки)) КАК ОстаткиТоваровОбороты
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
,
Номенклатура В
(ВЫБРАТЬ
ВТОстатки.Номенклатура
ИЗ
ВТОстатки КАК ВТОстатки)) КАК ЦеныНоменклатурыСрезПоследних
ПО ОстаткиТоваровОбороты.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
ГДЕ
ОстаткиТоваровОбороты.КоличествоОборот > 0
Да. Тут запросы не сложные. Но до конца все равно не понимаю… :( Напомните мыло куда вопрос скинуть?
mg.spec8ru @ gmail.com
Задание выполнено.
1. Первую задачу решил использованием внутреннего соединения. При этом условие с NULL становится лишним и его можно убрать.
2. Запрос несложный, сортировку решил путем добавления вычисляемого поля через конструктцию ВЫБОР, по этому полю и осуществляется сортировка.
3. Запрос практически полностью переделал. Основной таблицей сделал таблицу остатков, к ней левым соединением добавляю актуальную цену товара и документы закупки (хотя здесь возможно правильнее было бы сделать регистр оборотов)
ДЗ № 9 выполнено.
1. ЛЕВОЕ СОЕДИНЕНИЕ заменил на ВНУТРЕННЕЕ
2. Создал поле, которое заполняю цифрами для сортировки (либо продажи, либо остатки) – по нему и сортирую
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура КАК Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток,
ПродажиОбороты.КоличествоОборот КАК Продажи,
ВЫБОР
КОГДА ПродажиОбороты.КоличествоОборот > 100
ТОГДА ПродажиОбороты.КоличествоОборот
ИНАЧЕ ОстаткиТоваровОстатки.КоличествоОстаток
КОНЕЦ КАК SortField
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ПО (ПродажиОбороты.Номенклатура = ОстаткиТоваровОстатки.Номенклатура)
И ((НЕ ПродажиОбороты.КоличествоОборот ЕСТЬ NULL ))
УПОРЯДОЧИТЬ ПО
SortField УБЫВ
3. Пакет:
Запрос № 1. Положил во временную таблицу “Остатки” номенклатуры.
Запрос № 2. Выбрал контрагентов и номенклатуру во временную таблицу “Закупки”. Хотя считаю, что оптимальней было бы не по документам бегать, а добавить оборотный регистр накопления “Закупки” получить обороты из него.
Запрос № 3. Соединил “закупки” и”Остатки” и цены номенклатуры внутренним соединением.
P.S. Кстати, установил себе IE9 и не могу теперь отправлять комменты…. приходится с другой машины это делать….
Интересно, на совместимость с ИЕ9 не проверяли. Учтем информацию..
А куда девалось 10 домашнее задание?
По какой-то причине пропала запись.
Сейчас воскресили, проверьте..
все на месте:))
Задание выполнено.
Так вышло, что только сейчас до него добрался. Постараюсь следующие задания выполнять оперативно.
1) В первом случае использовал пакетный запрос с одной ВТ.
Для отсекания отрицательных остатков добавил проверку: ОстаткиТоваровОстатки.КоличествоОстаток > 0.
ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ ВТПродажи
ИЗ
РегистрНакопления.Продажи.Обороты(&ДатаНач, &ДатаКон, , ) КАК ПродажиОбороты
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТПродажи.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток КАК КолОстаток,
ВТПродажи.КоличествоОборот КАК КолПродажа
ИЗ
ВТПродажи КАК ВТПродажи
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки(
&ДатаКон,
Номенклатура В
(ВЫБРАТЬ
ВТПродажи.Номенклатура
ИЗ
ВТПродажи КАК ВТПродажи)) КАК ОстаткиТоваровОстатки
ПО ВТПродажи.Номенклатура = ОстаткиТоваровОстатки.Номенклатура
И (ОстаткиТоваровОстатки.КоличествоОстаток > 0)
2) Для решения второй задачи немного модернизировал 1-й запрос. Добавил поле для сортировки, значение которого определяется следующим образом:
если объем продаж превышает 100, тогда в качестве сортировки берется проданное количество, иначе количество остатка. Сортировка по убыванию.
Т.к. по условию задачи сказано, что остаток анализируется на самый актуальный момент, а продажи за весь период, я не задавал периоды виртуальных таблиц.
ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ ВТПродажи
ИЗ
РегистрНакопления.Продажи.Обороты(, , , ) КАК ПродажиОбороты
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТПродажи.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток КАК КолОстаток,
ВТПродажи.КоличествоОборот КАК КолПродажа,
ВЫБОР
КОГДА ВТПродажи.КоличествоОборот > 100
ТОГДА ВТПродажи.КоличествоОборот
ИНАЧЕ ОстаткиТоваровОстатки.КоличествоОстаток
КОНЕЦ КАК Сортировка
ИЗ
ВТПродажи КАК ВТПродажи
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки(
,
Номенклатура В
(ВЫБРАТЬ
ВТПродажи.Номенклатура
ИЗ
ВТПродажи КАК ВТПродажи)) КАК ОстаткиТоваровОстатки
ПО ВТПродажи.Номенклатура = ОстаткиТоваровОстатки.Номенклатура
И (ОстаткиТоваровОстатки.КоличествоОстаток > 0)
УПОРЯДОЧИТЬ ПО
Сортировка УБЫВ
3) Третий запрос является абсолютно некорректным.
Во 2-м пакетном запросе анализируются обороты регистра остатки товаров. Для исключения лишних соединений с документами отгрузки я использовал приведение типа Регистратора к типу
“Документ.ПоступлениеТоваровИУслуг”.
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура КАК Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток КАК КолОстаток
ПОМЕСТИТЬ ВТОстатки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки(, ) КАК ОстаткиТоваровОстатки
ГДЕ
ОстаткиТоваровОстатки.КоличествоОстаток > 0
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
ВЫРАЗИТЬ(ОстаткиТоваровОбороты.Регистратор КАК Документ.ПоступлениеТоваровИУслуг).Контрагент КАК Поставщик,
ОстаткиТоваровОбороты.Номенклатура
ПОМЕСТИТЬ ВТПоставщики
ИЗ
РегистрНакопления.ОстаткиТоваров.Обороты(
,
,
Регистратор,
Номенклатура В
(ВЫБРАТЬ
ВТОстатки.Номенклатура
ИЗ
ВТОстатки КАК ВТОстатки)) КАК ОстаткиТоваровОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТПоставщики.Поставщик КАК Поставщик,
ВТОстатки.Номенклатура,
ВТОстатки.КолОстаток КАК КолОстаток,
ЦеныНоменклатурыСрезПоследних.Цена
ИЗ
ВТОстатки КАК ВТОстатки
ЛЕВОЕ СОЕДИНЕНИЕ ВТПоставщики КАК ВТПоставщики
ПО ВТОстатки.Номенклатура = ВТПоставщики.Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
,
Номенклатура В
(ВЫБРАТЬ
ВТОстатки.Номенклатура
ИЗ
ВТОстатки КАК ВТОстатки)) КАК ЦеныНоменклатурыСрезПоследних
ПО ВТОстатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
УПОРЯДОЧИТЬ ПО
Поставщик,
КолОстаток
ДЗ 9 выполнил.
1. Внутренне соединение вмсето левого.
2. решил созданием доп вычисляемой колонки по которой в итоге сортирую
ВЫБРАТЬ
ОстаткиТоваровОстатки.КоличествоОстаток КАК КоличествоОстаток,
ОстаткиТоваровОстатки.Номенклатура
ПОМЕСТИТЬ Остатки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки(, Номенклатура.НоменклатурнаяГруппа = &НомГруппа) КАК ОстаткиТоваровОстатки
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
МАКСИМУМ(Остатки.КоличествоОстаток) КАК КоличествоОстаток
ПОМЕСТИТЬ МаксимумОстатка
ИЗ
Остатки КАК Остатки
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток,
ПродажиОбороты.КоличествоОборот,
ВЫБОР
КОГДА ПродажиОбороты.КоличествоОборот > 100
ТОГДА ПродажиОбороты.КоличествоОборот
ИНАЧЕ ОстаткиТоваровОстатки.КоличествоОстаток – МаксимумОстатка.КоличествоОстаток
КОНЕЦ КАК Поле1
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки(, Номенклатура.НоменклатурнаяГруппа = &НомГруппа) КАК ОстаткиТоваровОстатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ПО ОстаткиТоваровОстатки.Номенклатура = ПродажиОбороты.Номенклатура,
МаксимумОстатка КАК МаксимумОстатка
УПОРЯДОЧИТЬ ПО
Поле1 УБЫВ
3. Полностью переписал запрос- добавил вт по остаткам, убрал полные соединения, добавил индексы и тд.
в итоге получилось:
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура КАК Номенклатура
ПОМЕСТИТЬ ТоварыНаОстатках
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки(НЕОПРЕДЕЛЕНО, ) КАК ОстаткиТоваровОстатки
ГДЕ
ОстаткиТоваровОстатки.КоличествоОстаток > 0
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
ПоступлениеТоваровТовары.Номенклатура КАК Номенклатура,
ПоступлениеТоваров.Контрагент
ПОМЕСТИТЬ Контрагенты
ИЗ
Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
ПО ПоступлениеТоваровТовары.Ссылка = ПоступлениеТоваров.Ссылка
ГДЕ
ПоступлениеТоваровТовары.Номенклатура В
(ВЫБРАТЬ
ТоварыНаОстатках.Номенклатура
ИЗ
ТоварыНаОстатках КАК ТоварыНаОстатках)
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ТоварыНаОстатках.Номенклатура КАК Номенклатура,
ЦеныНоменклатурыСрезПоследних.Цена,
Контрагенты.Контрагент
ИЗ
ТоварыНаОстатках КАК ТоварыНаОстатках
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
НЕОПРЕДЕЛЕНО,
Номенклатура В
(ВЫБРАТЬ
ТоварыНаОстатках.Номенклатура
ИЗ
ТоварыНаОстатках КАК ТоварыНаОстатках)) КАК ЦеныНоменклатурыСрезПоследних
ПО ТоварыНаОстатках.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ Контрагенты КАК Контрагенты
ПО ТоварыНаОстатках.Номенклатура = Контрагенты.Номенклатура
УПОРЯДОЧИТЬ ПО
Номенклатура
Задание выполнил.
1. Необходимо заменить соединение на внутреннее и убрать условие на NULL.
2. Необходимо добавить поле, по которому и будет идти сортировка.
3. Честно говоря, просто переписал запрос.
Задание выполнено.
Задание выполнил.
1. Тоже использовал внутренее соединение.
2. Дополнял запрос из первого пункта.
3. Переписал с использованием пакетов
Задание выполнено.
1. Вместо левого соединения сделать внутреннее, чтобы попадали только те товары, которые есть в обеих таблицах. И соответственно условие на NULL нужно убрать. Второй вариант – пакеты. В первом пакете выбрать Продажи, во втором – из остатков только ту номенклатуру, которая есть в первом пакете и остатки которой больше нуля.
2. Использовался правильный запрос из предыдущей задачи. Добавлены условия: таблица Продажи – ограничения по периоду; Остатки – на момент времени. Добавлено дополнительное поле. Когда продажи больше 100, тогда поле – объем продаж, иначе – 0. Сортировка сначала по этому полу, затем по остаткам.
3. Запрос улыбнул. Чем помогать Виктору оптимизировать его гениальный запрос, лучше написать новый. Из виртуальной таблицы ОстаткиИОбороты выбираем номенклатуру, которая есть на остатках, которая продавалась и регистратор – Поступление товаров и услуг (контрагент из регистратора). Далее соединяем со срезом последних цен.
1. Необходимо использовать Внутренее соединение. А так же необходимо добавить условие, что остаток больше 0, в противном случае могут попадать товары с отрицательными остатками.
2. Создаем дополнительные поля: «Сортировка1уровня», которое заполняем значением 1 если объем продаж превышает 100 и значением 2 — в остальных случаях. И поле «Сортировка2уровня», где указываем объем продаж при превышении показателя 100 ед. или остаток товара. Далее остается выполнить сортировку по этим полям
3.
ВЫБРАТЬ РАЗЛИЧНЫЕ
ОстаткиТоваровОстатки.Номенклатура
ПОМЕСТИТЬ ВТ_Остатки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ГДЕ
ОстаткиТоваровОстатки.КоличествоОстаток > 0
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
ПоступлениеТоваровТовары.Ссылка.Контрагент КАК Контрагент,
ПоступлениеТоваровТовары.Номенклатура КАК Номенклатура,
ЦеныНоменклатурыСрезПоследних.Цена КАК Цена
ИЗ
ВТ_Остатки КАК ВТ_Остатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
ПО ВТ_Остатки.Номенклатура = ПоступлениеТоваровТовары.Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних
ПО ВТ_Остатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
УПОРЯДОЧИТЬ ПО
Номенклатура,
Контрагент,
Цена
При такой организации запроса:
удалось сократить число выборок,
удалось отказаться от вложенных запросов,
получили более читаемый текст запроса.
Выполнено. Немного отстал
ДЗ 9 Выполнил.
1. В запросе использовать внутреннее соединение, тогда на null можно и не проверять
2. Ввод дополнительного поля в запросе, которое заполняется при объеме продаж больше 100, дальше использование его сортировке.
3. Не использовать полное соединение, лучше сделать пакет запросов. Вначале определим таблицу с номенклатурой по которой есть остатки. Дальше уже производим выбор из документов поступления только по позициям которые есть в 1 таблице и производим соединение с РС по ценам.
1. Либо меняем вид соединения на внутренее и убираем условие по есть null, либо остатки кладем в пакет и соединяем его во втором пакете с продажами по внутреннему соединению.
http://prntscr.com/1as04
2. Берем запрос с первой задачи (с пакетами), дополняем его полем упорядочивания
ВЫБОР
КОГДА ПродажиОбороты.КоличествоОборот > 100
ТОГДА ПродажиОбороты.КоличествоОборот
ИНАЧЕ 0
КОНЕЦ КАК Сортировка
ВЫБОР КОГДА ПродажиОбороты.КоличествоОборот > 100 ТОГДА ПродажиОбороты.КоличествоОборот ИНАЧЕ 0 КОНЕЦ КАК Сортировка
Делаем сортировку по полю сортировка по убыванию, и по остатку тоже по убыванию.
http://prntscr.com/1as6b
3. В первом пакете выбираем остатки. Во втором пакете выбираем контрагентов из документов с условием что номенклатура есть в пакете 1. В финальном запросе, соединяем Остатки и Контрагентов по внутренними соединению + с виртуальной таблицей среза последних номенклатуры, в качестве параметра указываем что номенклатура берется из пакета 1. Выставляем итоги по номенклатуре.
http://prntscr.com/1as9k
ДЗ № 9 выполнила.
Задача № 1. Заменить ЛЕВОЕ соединение на ВНУТРЕННЕЕ и убрать условие проверки на NULL.
Задача № 2. Решилась вот таким запросом:
ВЫБРАТЬ
ПродажиОбороты.Номенклатура,
ПродажиОбороты.КоличествоОборот КАК КоличествоОборот
ПОМЕСТИТЬ ПродажиЗаПериод
ИЗ
РегистрНакопления.Продажи.Обороты(&ДатаНач, &ДатаКон, , ) КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ЕСТЬNULL(ОстаткиТоваровОстатки.Номенклатура, ПродажиЗаПериод.Номенклатура) КАК Номенклатура,
ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток,
ЕСТЬNULL(ПродажиЗаПериод.КоличествоОборот, 0) КАК КоличествоОборот
ПОМЕСТИТЬ ПродажиОбороты
ИЗ
ПродажиЗаПериод КАК ПродажиЗаПериод
ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ПО ПродажиЗаПериод.Номенклатура = ОстаткиТоваровОстатки.Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ПродажиОбороты.Номенклатура,
ПродажиОбороты.КоличествоОстаток КАК КоличествоОстаток,
ПродажиОбороты.КоличествоОборот,
ВЫБОР
КОГДА ПродажиОбороты.КоличествоОборот > 100
ТОГДА ПродажиОбороты.КоличествоОборот
ИНАЧЕ 0
КОНЕЦ КАК ПолеСортировки
ИЗ
ПродажиОбороты КАК ПродажиОбороты
УПОРЯДОЧИТЬ ПО
ПолеСортировки УБЫВ,
КоличествоОстаток УБЫВ
Задача № 3. Переписала запрос, т.к. считаю, что лучше брать данные о контрагентах не из документов Поступления,
а из регистраторов, используя обороты регистра ОстаткиТоваров.
Т.к. нужна номенклатура, имеющаяся на остатках, то и выбираем ее из остатков по регистру ОстаткиТоваров.
Получившийся запрос:
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура
ПОМЕСТИТЬ Остатки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
ОстаткиТоваровОбороты.Номенклатура,
ОстаткиТоваровОбороты.Регистратор.Контрагент КАК Контрагент,
ЦеныНоменклатурыСрезПоследних.Цена
ИЗ
РегистрНакопления.ОстаткиТоваров.Обороты(
,
,
Регистратор,
Номенклатура В
(ВЫБРАТЬ
Остатки.Номенклатура
ИЗ
Остатки КАК Остатки)) КАК ОстаткиТоваровОбороты
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних
ПО ОстаткиТоваровОбороты.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
ГДЕ
ОстаткиТоваровОбороты.КоличествоПриход <> 0
Задание 1. Убрать из условий соединения строку “ПродажиОбороты.КоличествоОборот ЕСТЬ НЕ NULL” и перенести ее в раздел запроса “условия”.
Задание 2. Используем пакет запросов. В первом запросе получаем номенклатуру и количество с остатками, затем таблицу-результат запроса 1 соединяем с виртуальной таблицей “Продажи” по номенклатуре. Для сортировки по количеству проданных товаров, если количество продажи больше 100 делаем дополнительное поле сортировки, для которого прописываем выражение:
ВЫБОР КОГДА Продажи.Количество>100 ТОГДА Продажи.Количество ИНАЧЕ 0 КОНЕЦ;
Сортировку делаем по вспомогательному полю сортировки по убыванию, затем – по остатку по убыванию.
Задача 3. Используем пакет запросов. В первом запросе получаем товары, которые есть на складе. Результат этого запроса используем для отбора, указываемом в виртуально таблице ЦеныНоменклатуры.СрезПоследних. Также делаем полное соединение таблицы номенклатуры на остатке с таблицей табличной части документа закупки.
Также данные по закупкам выгружаю во временную таблицу во втором запросе пакета.
Принцип получения данных по поставщикам, а также полное соединение таблицы номенклатуры и поставщиков и цен номенклатуры оставил без изменения.
Неожиданно вырезали апендицит, сесть за комп получилось только сейчас.
1 часть:
ЛЕВОЕ СОЕДИНЕНИЕ необходимо заменить на ВНУТРЕННЕЕ, и убрать лишнее условие “И (ПродажиОбороты.КоличествоОборот ЕСТЬ НЕ NULL )”
2 часть:
– Выбрал остатки товаров и обороты продаж поместил в ТЗОстаткиИПродажи
– Получил максимум остатка на складе поместил в ТЗМаксимумОстатка
– Выбрал Данные из ТЗОстаткиИПродажи и ТЗМаксимумОстатка, создал поле Упорядочивания в котором если Оборот >100 тогда Оборот+МаксимумОстатка, иначе Остаток, и упорядочил по убыванию по этому полю.
– результат http://s007.radikal.ru/i302/1012/8e/6ede5dc5ebb1.jpg
3 часть:
– убрал обращение к справочнику Товары;
– заменил выборку документов поступления на обращение к регистру накопления ОстаткиТоваров
– убрал проверку на наличие остатка из ГДЕ
Построение запроса:
– Выбрал данные из ОстаткиТоваров.ОстаткиИОбороты с движение по регистратору, отобрал только приходы поместил в ТЗНоменклатураПоставщик (выбрал не повторяющиеся);
– Выбираем данные из ОстаткиТоваров.Остатки Левым соединением с ТЗНоменклатураПоставщик по номенклатуре, и левым соединением с ЦеныНоменклатуры.СрезПоследних по Номенклатуре.
– результат http://i039.radikal.ru/1012/35/58cad8789fbf.jpg
Все ок.
Поправляйтесь!
1. использовать ВНУТРЕННЕЕ СОЕДИНЕНИЕ, убрать в условии соединения проверку на NULL или во временную таблицу (ВТ) получить данные одного источника и сделать внутреннее соединение с виртуальной таблицей второго источника, в параметрах которой поставить ограничение на вхождение Номенклатуры в ВТ. Но 2-й вариант в случае, если доля “лишней” номенклатуры окажется очень мала в общей массе, полагаю, может оказаться более медленным. ПС. если нет необходимости анализировать весь период ведения учета в базе, ограничить период выборки оборотов параметрами виртуальной таблицы оборотов.
2. ВЫБРАТЬ ОстаткиТоваровОстатки.Номенклатура, ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) КАК Количество, ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КАК Остаток, ВЫБОР КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100 ТОГДА 0 ИНАЧЕ 1 КОНЕЦ КАК УровеньСортировки, ВЫБОР КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100 ТОГДА -ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) ИНАЧЕ ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КОНЕЦ КАК ЗначениеСортировки ИЗ РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты ПО (ПродажиОбороты.Номенклатура = ОстаткиТоваровОстатки.Номенклатура) УПОРЯДОЧИТЬ ПО УровеньСортировки, ЗначениеСортировки ВЫБРАТЬ ОстаткиТоваровОстатки.Номенклатура, ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) КАК Количество, ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КАК Остаток, ВЫБОР КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100 ТОГДА 0 ИНАЧЕ 1 КОНЕЦ КАК УровеньСортировки, ВЫБОР КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100 ТОГДА -ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) ИНАЧЕ ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КОНЕЦ КАК ЗначениеСортировкиИЗ РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты ПО (ПродажиОбороты.Номенклатура = ОстаткиТоваровОстатки.Номенклатура)
УПОРЯДОЧИТЬ ПО УровеньСортировки, ЗначениеСортировки
В данном случае можно было обойтись одним полем доп сортировки
Немного усложнил задачу, дабы показать универсальность решения. Итак, добавил условие, что в промежутке в оборотах между 100 и 200 сортировка должна быть, к примеру по Остаткам по убыванию, а с 200 до 300 вообще по возрастанию Наименования номенклатуры :).
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) КАК Количество,
ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КАК Остаток,
ВЫБОР
КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 300 ТОГДА 3
КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 200 ТОГДА 2
КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100 ТОГДА 1
ИНАЧЕ 0
КОНЕЦ КАК УровеньСортировки,
ВЫБОР
КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 300 ТОГДА -ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0)
КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 200 ТОГДА ОстаткиТоваровОстатки.Номенклатура
КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100 ТОГДА -ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0)
ИНАЧЕ ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0)
КОНЕЦ КАК ЗначениеСортировки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ПО (ПродажиОбороты.Номенклатура = ОстаткиТоваровОстатки.Номенклатура)
УПОРЯДОЧИТЬ ПО
УровеньСортировки Убыв,
ЗначениеСортировки
При этом, если необходимый порядок сортировки отличается от сортировки поля ЗначениеСортировки, для числовых данных ставим вперед минус.
3. Сделал. Использовал временные таблицы и получал Поставщика из соединения таблицы ОстаткиТоваров с Документ.ПоступлениеТоваров по Регистратор=Ссылка.
1. использовать ВНУТРЕННЕЕ СОЕДИНЕНИЕ, убрать в условии соединения проверку на NULL или во временную таблицу (ВТ) получить данные одного источника и сделать внутреннее соединение с виртуальной таблицей второго источника, в параметрах которой поставить ограничение на вхождение Номенклатуры в ВТ. Но 2-й вариант в случае, если доля “лишней” номенклатуры окажется очень мала в общей массе, полагаю, может оказаться более медленным. ПС. если нет необходимости анализировать весь период ведения учета в базе, ограничить период выборки оборотов параметрами виртуальной таблицы оборотов.
2. Немного усложнил задачу, дабы показать универсальность решения. Итак, добавил условие, что в промежутке в оборотах между 100 и 200 сортировка должна быть, к примеру по Остаткам по убыванию, а с 200 до 300 вообще по возрастанию Наименования номенклатуры :).ВЫБРАТЬ ОстаткиТоваровОстатки.Номенклатура, ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) КАК Количество, ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КАК Остаток, ВЫБОР КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 300 ТОГДА 3 КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 200 ТОГДА 2 КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100 ТОГДА 1 ИНАЧЕ 0 КОНЕЦ КАК УровеньСортировки, ВЫБОР КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 300 ТОГДА -ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 200 ТОГДА ОстаткиТоваровОстатки.Номенклатура КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100 ТОГДА -ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) ИНАЧЕ ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КОНЕЦ КАК ЗначениеСортировкиИЗ РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты ПО (ПродажиОбороты.Номенклатура = ОстаткиТоваровОстатки.Номенклатура)
УПОРЯДОЧИТЬ ПО УровеньСортировки Убыв, ЗначениеСортировки
При этом, если необходимый порядок сортировки отличается от сортировки поля ЗначениеСортировки, для числовых данных ставим вперед минус.
3. Сделал. Использовал временные таблицы и получал Поставщика из соединения таблицы ОстаткиТоваров с Документ.ПоступлениеТоваров по Регистратор=Ссылка.
Готово.
1. Внутреннее соединение
2. Добавление дополнительных полей для сортировки.
3. Использование ВТ.
Задание выполнил.
1. Убрал соединение по не Null, по номенклатуре сделал внутреннее соединение. Время выполнения запроса до 0,0656 после 0,0035.
2. Сформировал поле для сортировки с помощью:
ВЫБОР
КОГДА ПродажиОбороты.КоличествоОборот > 100
ТОГДА ПродажиОбороты.КоличествоОборот
ИНАЧЕ ОстаткиТоваровОстатки.КоличествоОстаток
КОНЕЦ КАК ПолеСортировки
3. Запрос переделал полностью.
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ЦеныНоменклатурыСрезПоследних.Цена
ПОМЕСТИТЬ ВтЦены
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних
ПО ОстаткиТоваровОстатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
ПоступлениеТоваровИУслугТовары.Ссылка.Контрагент,
ПоступлениеТоваровИУслугТовары.Номенклатура
ПОМЕСТИТЬ ВТКонтрагент
ИЗ
Документ.ПоступлениеТоваровИУслуг.Товары КАК ПоступлениеТоваровИУслугТовары
ГДЕ
ПоступлениеТоваровИУслугТовары.Ссылка.Проведен
И ПоступлениеТоваровИУслугТовары.Номенклатура В
(ВЫБРАТЬ
ВтЦены.Номенклатура
ИЗ
ВтЦены КАК ВтЦены)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВтЦены.Номенклатура,
ВтЦены.Цена,
ВТКонтрагент.Контрагент
ИЗ
ВтЦены КАК ВтЦены
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТКонтрагент КАК ВТКонтрагент
ПО ВтЦены.Номенклатура = ВТКонтрагент.Номенклатура
Замер производительности уменьшение времени выполнения не показал. Скорее всего из-за не большого объема данных, время на создание временных таблиц оказало в данном случае существенное влияние.
Сделано.
1. Достаточно Левое соединение заменить на Правое или Внутреннее – результат будет одинаковый. Попутный вопрос – какое из них будет быстрее?
2. У меня получился запрос в 4 пакета. Жду решения, как можно сделать лучше.
3. Нужно исправить следующие моменты: 1) Вместо спр. Номенклатура нужно использовать вирт. табл. РН ОстаткиТоваров.Остатки и вместо условия с вложенным запросом использовать такое: ОстаткиТоваровОстатки.КоличествоОстаток > 0. 2) Вместо вложенного запроса Закупки использовать временную таблицу с построением индекса по номенклатуре.
3) Условие по контрагенту перенести в пакет с врем. таблицей и исправить его на такой: ТоварыДок.Ссылка.Контрагент <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка).
По 3 пункту: и конечно же, заменить полные соединения на соединения с таблицей остатков.
1. Правое (левое) и внутреннее соединение решают немного разные задачи.
По скорости они сопоставимы.
Задача 1
Сделать внутреннее содинение и условие связи ПродажиОбороты.КоличествоОборот ЕСТЬ НЕ NULL убрать
Задача 2
ВЫБРАТЬ
ЕСТЬNULL(ОстаткиТоваровОстатки.Номенклатура, ПродажиОбороты.Номенклатура) КАК Товар,
ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КАК Остаток,
ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) КАК Продажи,
ВЫБОР
КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 20
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ * ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) КАК Поле2,
ВЫБОР
КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) <= 20
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ * ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КАК Поле3
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ПО ПродажиОбороты.Номенклатура = ОстаткиТоваровОстатки.Номенклатура
УПОРЯДОЧИТЬ ПО
Поле2 УБЫВ,
Поле3 УБЫВ
Задача 3
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток
ПОМЕСТИТЬ ВТОстатки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
ПоступлениеТоваровИУслугТовары.Номенклатура КАК Номенклатура,
ПоступлениеТоваровИУслугТовары.Ссылка.Контрагент
ПОМЕСТИТЬ ВТЗакупки
ИЗ
Документ.ПоступлениеТоваровИУслуг.Товары КАК ПоступлениеТоваровИУслугТовары
ГДЕ
ПоступлениеТоваровИУслугТовары.Номенклатура В
(ВЫБРАТЬ
ВТОстатки.Номенклатура
ИЗ
ВТОстатки КАК ВТОстатки)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТЗакупки.Номенклатура,
ВТЗакупки.Контрагент,
ВТОстатки.КоличествоОстаток,
ЦеныСрезПоследних.Цена
ИЗ
ВТЗакупки КАК ВТЗакупки
ЛЕВОЕ СОЕДИНЕНИЕ ВТОстатки КАК ВТОстатки
ПО ВТЗакупки.Номенклатура = ВТОстатки.Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цены.СрезПоследних КАК ЦеныСрезПоследних
ПО ВТЗакупки.Номенклатура = ЦеныСрезПоследних.Цена
Классное и простое решение по 2 пункту. У меня гораздо сложнее… Спасибо.
1.За основу взят рег.Продажи.Обороты т.к. в условии: только продаваемая за период номенклатура иначе будет возвращаться NULL в Оборотах где их небыло. К нему добавил рег.ОстаткиТоваровОстатки Внутренним соединением, у которого Остаток > 0
2.Сортировать можно только Поле. Поэтому в Поле1 попало Количество с Расход > 100, а в Поле2 КонечныйОстаток <= 100. Упорядочил поля по Убыванию.
3.За основу рег.ОстаткиТоваров т.к. в условии номенклатура только с остатками. ЛевымСоединением рег.Цена и ЛевымСоединением Документ.ПоступлениеТоваров.Товары и из ссылки достаем Контрагент. Помню, что доставать из Cсылки не Ice. + оговорка: каждый Контрагент поставляет свою номенклатуру Иначе светит партионный учет.
Задание выполнил.
по п.2 – один запрос к двум регистрам с двумя вспомогательными полями для сортировки : Приоритет и КоличествоДляСортировки
по п.3 – остатки выбираю во временную таблицу, потом соединение трех таблиц, отбор только по номенклатуре из остатков.
Задача 1
Поставила внутреннее соединение и убрала вторую таблиц связь по условию НЕ NULL
Задача 2
Пакетный запрос
Запрос 2
Продажи, для таблицы РегистрНакопления.Продажи.Обороты(&ДатаНачала, &ДатаКонца, , ) – заданы параметры по периоду
Добавлено поле сортировки
ПродажиОбороты.Номенклатура,
ВЫБОР
КОГДА ПродажиОбороты.КоличествоОборот > 100
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ
Группирока по Номенклатуре
Результат в таблицу ВТПродажи
Запрос 2
Остатки по условию вхождения Номенклатуры в таблицу ВТПродажи
Поле сортировки 0
Результат в таблицу ВТОстатки
Группирока по Номенклатуре
Запрос 3
Выбор из Таблиц ВТПродажи и ВТОстатки. Связь Таблиц ВТПродажи и ВТОстатки левое соединение по номенклатуре
Еще один реквизит ПолеСортировки1
ВЫБОР
КОГДА ВТПродажи.ПолеСортировки > 0
ТОГДА ВТПродажи.ПолеСортировки
ИНАЧЕ ВТОстатки.КвоОстаток
КОНЕЦ
Порядок
ПолеСортировки УБЫВ,
ПолеСортировки1 УБЫВ
Задача 3
Пакетный запрос
Запрос 1
Выбираем из таблицы РегистрНакопления.ОстаткиТоваров.Остатки ненулевые остатки помещаем в таблицу ВТОстатки
Запрос 2
Выбираем из РегистрСведений.ЦеныНоменклатуры.СрезПоследних В параметрах таблицы условие на вхождение номенклатуры в ВТОстатки в таблицу ВТЦеныНоменклатуры
Запрос 3
Выбираем из РегистрНакопления.ОстаткиТоваров.ОстаткиИОбороты
Периодичность Регистратор, вхождение номенклатуры в ВТОстатки
Условие ОстаткиТоваровОстаткиИОбороты.Регистратор ССЫЛКА Документ.ПоступлениеТоваров в таблицу ВТПоставщики
Группировка Номенклатура, Поставщик В Таблицу ВТПоставщики
Запрос 4
Из трех таблиц
ВТОстатки
ВТЦеныНоменклатуры
ВТПоставщики
Выбираем нужную информацию
Связи ВТОстатки и ВТЦеныНоменклатуры
ВТОстатки и ВТПоставщики по номенклатуре
Задание выполнено.
По первому и второму запросы совпадают (в моем решении), за исключением того, что во втором
добавилось соответствующее поле и сортировки.
По третьему запрос переписан с добавлением соединений и пакетов.
Скриншоты прилагаются
http://www.screencast.com/t/8RSWFWDy
http://www.screencast.com/t/FKTdf7pvAxjV
Задание выполнил.
1. в первой задаче достаточно левое соединение заменить на внутреннее и убрать условие по Null.
2. Выполнил через пакетный запрос: на первом и втором шагах помещаю в темпы таблицу остатков и таблицу оборотов, с индексированием поля номенклатура. На третьем шаге к оборотам лефт-джойню остатки и попутно через Case делаю специальное сортировочное поле:
ВЫБОР
КОГДА Продажи.КоличествоОборот > 100
ТОГДА Продажи.КоличествоОборот
ИНАЧЕ ЕСТЬNULL(Остатки.КоличествоОстаток, 0)
КОНЕЦ КАК ПолеСортировки
Результирующую таблицу засовываю опять в темп. В последнем запросе просто выбираю из последнего темпа нужные поля и упорядочиваю по убыванию по ПолеСортировки и КоличествоОстаток. Инджойнюсь результатом ;)
3. Запрос Виктора совсем космический. Поэтому, как отписывался коллега, я переписал запрос используя РН и РС.
Из всех ДЗ, это мне показалось самым простым. Наверное потому, что нет управляемых форм ;)
Сделала 1-е задание.
Для вывода номенклатуры, которая продавалась, достаточно убрать ЛЕВОЕ или поменять местами регистры, сделать ЛЕВОЕ для регистра продаж.
Работает и пакетным запросом с созданием временной таблицы для продаж.
Сделала 2-е задание.
Пакетный запрос с формированием временных таблиц
1)ВТПродажиОбороты из РегистрНакопления.Продажи.Обороты с проверкой ПродажиОбороты.КоличествоОборот>100
2)ВТПродажиОстатки из РегистрНакопления.ОстаткиТоваров.Остатки с СОЕДИНЕНИЕМ по номенклатуре с ВТПродажиОбороты
для получения Остаток
3)Запрос для полученик из Номенклатура, Продано, Остаток из ИЗ ВТПродажиОстатки с соединением с ВТПродажиОбороты по Номенклатуре и
УПОРЯДОЧИТЬ ПО
Остаток УБЫВ,
ВТПродажиОбороты.Больше100 УБЫВ
Сделала 3-е задание.
Необходимо убрать переименование источников, где возможно и изменить наименование на более информативное. После этого намного лучше видно, где именно запрос не оптимизирован. Информацию надо отсекать сначала, а не перебирать всю. Полное соединение дает перебор цен всего справочника номенклатуры, еще анализируются Различные. В этом запросе вытаскивается вся информация по ценам всех контрагентов, а только потом отсекается.
Надо обращаться к виртуальным таблицам регистров накопления, а не к документам. К документам медленнее в принципе и приходится выполнять еще проверку на проведение.
Лучше использовать временные таблицы и пакетный запрос, а не вложенный запрос. Хотя, в данном случае, можно и без временных таблиц, сделать запрос к виртуальным таблицам – регистра накопления для остатков товаров (с периодичностью Регистратор в параметрах для получения контрагента) и регистра сведения ЦеныНоменклатурыСрезПоследних.
По заданию отписался. Выполнил, но не вижу своего поста. Возможно он на модерации…но обычно они видны. А так уже запросы не сохранил :(, но по факту, пришел к выводу, что в поставленных задачах нет смысла использовать пакетные запросы, ибо не происходит повторного обращения к одним и тем же данным. Первая задача решается путем изменения левого соединения (в связях меняем местами таблицы) и установки условия на положительный остаток.
Во второй задаче использовал дополнительное поле вывода, сортировал сперва по нему, а потом по количеству. В допю поле помещал продажи больше 100.
В третьем случае неверно использовать таблицу документов. Правильнее отталкиваться от таблицы остатков на дату с ней связывать таблицу Закупки (для определения контрагентов) и потом уже получать срез последних на дату остатков (не использовать физическую таблицу цен)
Один комент попал в спам (такое бывает), но был успешно восстановлен.
А вот про использование пакетных запросов в данных задачах мы обсудим в решении ДЗ.
В первой задаче ПродажиОбороты.КоличествоОборот ЕСТЬ НЕ NULL нужно вынести в условие, а не в связи т.к. при левом соединении в результат попадают все записи из левой табл.
Вторая задача. Для сортировки пришлось добавлять новые поля. Работает.
ВЫБРАТЬ
ВЫБОР
КОГДА ОстаткиТоваровОстатки.Номенклатура <> NULL
ТОГДА ОстаткиТоваровОстатки.Номенклатура
ИНАЧЕ ПродажиОбороты.Номенклатура
КОНЕЦ КАК Товар,
ПродажиОбороты.КоличествоОборот КАК Оборот,
ОстаткиТоваровОстатки.КоличествоОстаток КАК Остаток,
ВЫБОР
КОГДА ПродажиОбороты.КоличествоОборот >= 100
ТОГДА 0
ИНАЧЕ 1
КОНЕЦ КАК Поле1,
ВЫБОР
КОГДА ПродажиОбороты.КоличествоОборот >= 100
ТОГДА ПродажиОбороты.КоличествоОборот
ИНАЧЕ ОстаткиТоваровОстатки.КоличествоОстаток
КОНЕЦ КАК Поле2
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки(&Момент, ) КАК ОстаткиТоваровОстатки
ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&Начало, &Конец, , ) КАК ПродажиОбороты
ПО ОстаткиТоваровОстатки.Номенклатура = ПродажиОбороты.Номенклатура
УПОРЯДОЧИТЬ ПО
Поле1,
Поле2 УБЫВ
Третье задание.
Запрос не эффективен так как:
– запрашивается много лишней информации, а потом отсекается ненужное
– Пользуется вложенными запросами, а удобнее временными таблицами
– Делает полное соединение Справочника.Номенклатура и перечня Номенклатуры из документов. В результате будет весь справочник номенклатуры
– Выбирать информацию лучше из регистров, а не из документов.
Поскольку в выборке должны быть только товары, имеющиеся на складе, нужно использовать регистр ОстаткиТоваров, его виртуальную таблицу ОстаткиИОбороты. В параметрах виртуальной таблицы указать периодичность по регистратору. И из регистратора вытащить контрагента
При этом нужно отслеживать, что бы тип регистратора был док ПоступлениеТоваров
Домашнее задание №9.
Задача 1.
Самый простой способ (но не самый производительный):
<code>
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток,
ПродажиОбороты.КоличествоОборот
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ПО ОстаткиТоваровОстатки.Номенклатура = ПродажиОбороты.Номенклатура
</code>
Более оптимальный вариант:
<code>
ВЫБРАТЬ
ПродажиОбороты.Номенклатура,
ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ ВТПродажи
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток КАК Остаток,
ВТПродажи.КоличествоОборот КАК Продано
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки(
,
Номенклатура В
(ВЫБРАТЬ
ВТПродажи.Номенклатура
ИЗ
ВТПродажи КАК ВТПродажи)) КАК ОстаткиТоваровОстатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТПродажи КАК ВТПродажи
ПО ОстаткиТоваровОстатки.Номенклатура = ВТПродажи.Номенклатура
</code>
Задача 2.
<code>
ВЫБРАТЬ
ПродажиОбороты.Номенклатура,
ПродажиОбороты.КоличествоОборот,
ВЫБОР
КОГДА ПродажиОбороты.КоличествоОборот > 100
ТОГДА ПродажиОбороты.КоличествоОборот
ИНАЧЕ 0
КОНЕЦ КАК СортировкаПоПродажам
ПОМЕСТИТЬ ВТПродажи
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ЕСТЬNULL(ОстаткиТоваровОстатки.Номенклатура, ВТПродажи.Номенклатура) КАК Номенклатура,
ЕСТЬNULL(ВТПродажи.КоличествоОборот, 0) КАК Продано,
ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КАК Остаток,
ЕСТЬNULL(ВТПродажи.СортировкаПоПродажам, 0) КАК СортировкаПоПродажам
ПОМЕСТИТЬ ВТПродажиОстатки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ПОЛНОЕ СОЕДИНЕНИЕ ВТПродажи КАК ВТПродажи
ПО ОстаткиТоваровОстатки.Номенклатура = ВТПродажи.Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТПродажиОстатки.Номенклатура,
ВТПродажиОстатки.Продано,
ВТПродажиОстатки.Остаток КАК Остаток
ИЗ
ВТПродажиОстатки КАК ВТПродажиОстатки
УПОРЯДОЧИТЬ ПО
ВТПродажиОстатки.СортировкаПоПродажам УБЫВ,
Остаток УБЫВ
</code>
Задача 3.
<code>
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток
ПОМЕСТИТЬ ВТОстатки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ПоступлениеТоваровИУслугТовары.Номенклатура,
ПоступлениеТоваровИУслугТовары.Ссылка.Контрагент,
МАКСИМУМ(ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.цена, 0)) КАК Цена
ИЗ
Документ.ПоступлениеТоваровИУслуг.Товары КАК ПоступлениеТоваровИУслугТовары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
,
Номенклатура В
(ВЫБРАТЬ
ВТОстатки.Номенклатура
ИЗ
ВТОстатки КАК ВТОстатки)) КАК ЦеныНоменклатурыСрезПоследних
ПО ПоступлениеТоваровИУслугТовары.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
ГДЕ
ПоступлениеТоваровИУслугТовары.Ссылка.Проведен
И ПоступлениеТоваровИУслугТовары.Номенклатура В
(ВЫБРАТЬ
ВТОстатки.Номенклатура
ИЗ
ВТОстатки КАК ВТОстатки)
</code>
По первой задаче.
Прогнал каждый из запросов раз по 10. В первом случае запрос отрабатывает быстрее, чем во втором.
В первом 0,002415
Во втором 0,003377
Значения средние.
Сергей, а что работает быстрее. Какие варианты сравниваются?
Автор ветки дает два запроса
Самый простой способ (но не самый производительный):
<code>
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток,
ПродажиОбороты.КоличествоОборот
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ПО ОстаткиТоваровОстатки.Номенклатура = ПродажиОбороты.Номенклатура
</code>
Более оптимальный вариант:
<code>
ВЫБРАТЬ
ПродажиОбороты.Номенклатура,
ПродажиОбороты.КоличествоОборот
ПОМЕСТИТЬ ВТПродажи
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток КАК Остаток,
ВТПродажи.КоличествоОборот КАК Продано
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки(
,
Номенклатура В
(ВЫБРАТЬ
ВТПродажи.Номенклатура
ИЗ
ВТПродажи КАК ВТПродажи)) КАК ОстаткиТоваровОстатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТПродажи КАК ВТПродажи
ПО ОстаткиТоваровОстатки.Номенклатура = ВТПродажи.Номенклатура
</code>
Та вот. Первый вариант, который самый простой, но не самый производительный на фаловой базе показывает лучшие результаты в замере производительности. Кроме этого, на e-mail отправил описание ситуации, которая меня смущает, при прочих равных, пакетный запрос работает в 60-т раз медленнее. Даже на серверной базе. Подробности в письме были отправлены.
Ок, отличный вопрос. Рассмотрим в МГ.
Очень интересные результаты тестирования. Я думаю, что запросы тестировались на базе, где немного документов, по моему мнению 2-й вариант возможно будет работать быстрее на базе с большим количеством документов, тогда задание параметров виртуальных таблиц может дать выигрыш.
Задача 1. Если искать то, что продавалось, то нужно делать левое соединение с остатками, а не наоборот. Ну и для полного счастья добавить проверку на КоличествоОборот > 0
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток,
ПродажиОбороты.КоличествоОборот
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ПО ПродажиОбороты.Номенклатура = ОстаткиТоваровОстатки.Номенклатура
И (ПродажиОбороты.КоличествоОборот > 0)
Задача 2 – не вижу смысла пользоватся пакетами или вложенными запросами.
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток КАК КоличествоОстаток,
ВЫБОР
КОГДА ПродажиОбороты.КоличествоОборот ЕСТЬ NULL
ТОГДА 0
ИНАЧЕ ПродажиОбороты.КоличествоОборот
КОНЕЦ КАК Продажа,
ВЫБОР
КОГДА ПродажиОбороты.КоличествоОборот >= 100
ТОГДА ПродажиОбороты.КоличествоОборот
ИНАЧЕ 0
КОНЕЦ КАК Больше
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ПО ОстаткиТоваровОстатки.Номенклатура = ПродажиОбороты.Номенклатура
УПОРЯДОЧИТЬ ПО
Больше УБЫВ,
КоличествоОстаток УБЫВ
Задача 3
1) не понятно, зачем Виктор использует таблицу документа, если у него просят вывести товары, которые есть на сладе. т.е. 100% нужен запрос к таблице остатков.
2) Какой-то сложный запрос он использует. Опять-таки, мне кажется, что решение “в лоб” достаточно оптимально
ВЫБРАТЬ
ОстаткиНоменклатурыОстатки.Номенклатура,
ОстаткиНоменклатурыОстатки.КоличествоОстаток,
ЗакупкаОбороты.Контрагент,
ЦеныНоменклатурыСрезПоследних.Цена
ИЗ
РегистрНакопления.ОстаткиНоменклатуры.Остатки(&КонПериода, ) КАК ОстаткиНоменклатурыОстатки
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Закупка.Обороты КАК ЗакупкаОбороты
ПО ОстаткиНоменклатурыОстатки.Номенклатура = ЗакупкаОбороты.Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&КонПериода, ТипЦен = &ТипЦены) КАК ЦеныНоменклатурыСрезПоследних
ПО ОстаткиНоменклатурыОстатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
По 3 заданию:
В конфе нет регистра Закупка – это псевдоним таб. док. Поступления и по хорешуму период лучше не передавать в парам. ВТ да и проиндексировать не помешало бы..
Может быть стоит указать, что в задаче 3 Виктор написал запрос в какой-то прикладной конфигурации?
В конфигурацию придется добавить периодический (в пределах дня) регистр сведений ЦеныНоменклатуры. Измерение – Номенклатура. Ресурс – Цена.
Задача1. Выводим номенклатуру, которая есть на остатках и которая не продавалась.
Сделал пакетом запросов. В первом запросе из регистра продаж вытащил номенклатуру, которая продавалась. Во втором запросе обратился к остаткам номенклатуры через виртуальную таблицу остатков, указав в параметре виртуальной таблице, что номенклатура не должна входить в список проданных товаров:
ВЫБРАТЬ ПродажиОбороты.Номенклатура
ПОМЕСТИТЬ НоменклатураПродажи
ИЗ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ОстаткиТоваров.Номенклатура, ОстаткиТоваров.КоличествоОстаток
ИЗ РегистрНакопления.ОстаткиТоваров.Остатки( ,
(НЕ Номенклатура В
(ВЫБРАТЬ
Номенклатура ИЗ
НоменклатураПродажи))) КАК ОстаткиТоваров
Задача 2. Пакет запросов: в первом запросе получаем проданную номенклатуру и количество, во втором запросе связываем продажи с остатками по номенклатуре. Делаем полное соединение. Для сортировки по проданному количеству больше 100 делаем вспомогательное поле:
ВЫБОР КОГДА Продажи.КоличествоПродажи ЕСТЬ NULL ТОГДА 0
КОГДА Продажи.КоличествоПродажи > 100 ТОГДА Продажи.КоличествоПродажи
ИНАЧЕ 0
КОНЕЦ КАК ПродажиСортировка
В самом запросе сортируем сначала по вспомогательному полю по убыванию, затем – по убыванию остатка.
Запрос выглядит следующим образом:
ВЫБРАТЬ ПродажиОбороты.Номенклатура КАК Номенклатура, ПродажиОбороты.КоличествоОборот КАК КоличествоПродажи
ПОМЕСТИТЬ Продажи
ИЗ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ ЕСТЬNULL(Продажи.Номенклатура, Остатки.Номенклатура) КАК Номенклатура, ЕСТЬNULL(Продажи.КоличествоПродажи, 0) КАК Продано,
ВЫБОР КОГДА Продажи.КоличествоПродажи ЕСТЬ NULL ТОГДА 0
КОГДА Продажи.КоличествоПродажи > 100
ТОГДА Продажи.КоличествоПродажи
ИНАЧЕ 0
КОНЕЦ КАК ПродажиСортировка,
ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток
ИЗ
Продажи КАК Продажи
ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки КАК Остатки ПО Продажи.Номенклатура = Остатки.Номенклатура
УПОРЯДОЧИТЬ ПО
ПродажиСортировка УБЫВ,
Остаток УБЫВ
Задача 3.
Снова использовал пакет запросов.
В первом запросе получил список номенклатуры, которая есть на остатках. Далее этот список использую в отборе в параметре виртуальной таблицы «Цены номенклатуры.Срез последних», а также при обращении к табличной части документа «Поступление товаров» – делаю соединение с таблицей остатков товаров.
ВЫБРАТЬ Остатки.Номенклатура
ПОМЕСТИТЬ Остатки
ИЗ
РегистрНакопления.ОстаткиТоваров КАК Остатки
ГДЕ
Остатки.Количество > 0
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Остатки.Номенклатура, ПоступлениеТоваровТовары.Ссылка.Контрагент КАК Поставщик, ЦеныНоменклатурыСрезПоследних.Цена
ИЗ
Остатки КАК Остатки
ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
ПО (Остатки.Номенклатура = ПоступлениеТоваровТовары.Номенклатура И ПоступлениеТоваровТовары.Ссылка.Проведен)ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних( ,
Номенклатура В
(ВЫБРАТЬ
Остатки.Номенклатура
ИЗ Остатки КАК Остатки)) КАК ЦеныНоменклатурыСрезПоследнихПО (Остатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура)
Хочу уточнить задание: написано: в результат должна попасть та номенклатура, которая есть на остатках и которая НЕ продавалась. А в запросе стоит условие, что ПродажиОбороты.КоличествоОборот есть не null. Где опечатка в задании или в запросе? Может быть наоборот, нужно найти те товары, которые есть на складе и которые продавались? Иначе будет непонятна проблема с запросом.
Действительно ошибка в тексте.
Нужно искать номенклатуру, которая продавалась.
Текст ДЗ поправил.