Продвинутый курс. Домашнее задание №9
Очередное задание по 1-му блоку продвинутого курса.
Для выполнения рекомендуется изучить следующие главы 1-го блока.
Глава 8. Оптимизация производительности прикладных решений.
Глава 9. Оптимизация производительности при работе с БД.
В этой же теме необходимо написать отчет о выполнении задания.
— залогиньтесь.
Если не активировали токен — посмотрите видео-инструкцию (видео N5)
Если вы залогинены, у Вас активирован токен доступа, но вы все равно видите эту запись —
напишите нам на e-mail поддержки.
Задание сделал.
1. Видно по тексту, что не хватает условия ГДЕ. С этим условием запрос работает.
2. Сделал дополнительное поле, по которому настраивается сортировка. Важно, что сортировку требуется выполнить в одном направлении, иначе подбирали бы какие-то другие поля.
3. Обращает внимание наличие полных соединений, вложенных запросов, неоптимального условия. Полные соединения заменяем на левые и помещаем выборки во временные таблицы.
Есть просьба, если с ДЗ № 10 – может какой бонус выдать… простой расхолаживает…
Бонус будет, но чуть позже.
А сейчас ДЗ№10 :)
Отчет по ДЗ №9
1) Очевидно, что для решения задачи нужно использовать внутреннее соединение двух ВТ.
2) Вторую задачу я решил путем объединения двух таблиц продаж и остатков, затем их группировки с последующим упорядочиванием по доп. полю по заданному условию.
[code]
ВЫБРАТЬ
ИтоговаяТаблица.Номенклатура КАК Номенклатура,
ИтоговаяТаблица.Количество,
ИтоговаяТаблица.Остаток,
ВЫБОР
КОГДА ИтоговаяТаблица.Количество > 100
ТОГДА ИтоговаяТаблица.Количество
ИНАЧЕ ИтоговаяТаблица.Остаток
КОНЕЦ КАК ПолеСортировки
ИЗ
(ВЫБРАТЬ
ПродажиОстатки.Номенклатура КАК Номенклатура,
СУММА(ПродажиОстатки.Количество) КАК Количество,
СУММА(ПродажиОстатки.Остаток) КАК Остаток
ИЗ
(ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.КоличествоОборот КАК Количество,
0 КАК Остаток
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
0,
ОстаткиТоваровОстатки.КоличествоОстаток
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки) КАК ПродажиОстатки
СГРУППИРОВАТЬ ПО
ПродажиОстатки.Номенклатура) КАК ИтоговаяТаблица
УПОРЯДОЧИТЬ ПО
ПолеСортировки УБЫВ
[/code]
3) Переписал запрос сл. образом:
[code]
ВЫБРАТЬ РАЗЛИЧНЫЕ
ТоварыДок.Номенклатура КАК Номенклатура,
ТоварыДок.Ссылка.Контрагент КАК Поставщик
ПОМЕСТИТЬ ВТЗакупки
ИЗ
Документ.ПоступлениеТоваровИУслуг.Товары КАК ТоварыДок
ГДЕ
ТоварыДок.Ссылка.Проведен
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ВТЗакупки.Поставщик,
Цены.Цена
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ЛЕВОЕ СОЕДИНЕНИЕ ВТЗакупки КАК ВТЗакупки
ПО ОстаткиТоваровОстатки.Номенклатура = ВТЗакупки.Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены
ПО ОстаткиТоваровОстатки.Номенклатура = Цены.Номенклатура
ГДЕ
ОстаткиТоваровОстатки.КоличествоОстаток > 0
[/code]
1.В запросе следует использовать внутренее соендинение вместо левого.
2.Получилось вот так вот замысловато:
ВЫБРАТЬ
| ОстаткиТоваровОбороты.Номенклатура КАК Номенклатура,
| ОстаткиТоваровОбороты.КоличествоРасход
|ПОМЕСТИТЬ Продажи
|ИЗ
| РегистрНакопления.ОстаткиТоваров.Обороты КАК ОстаткиТоваровОбороты
|
|ИНДЕКСИРОВАТЬ ПО
| Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ОстаткиТоваровОстатки.Номенклатура КАК Номенклатура,
| ОстаткиТоваровОстатки.КоличествоОстаток
|ПОМЕСТИТЬ Остатки
|ИЗ
| РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
|
|ИНДЕКСИРОВАТЬ ПО
| Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Продажи.Номенклатура,
| Продажи.КоличествоРасход,
| Остатки.КоличествоОстаток,
| Продажи.КоличествоРасход КАК Сортировка
|ПОМЕСТИТЬ ПоПродажам
|ИЗ
| Продажи КАК Продажи
| ЛЕВОЕ СОЕДИНЕНИЕ Остатки КАК Остатки
| ПО Продажи.Номенклатура = Остатки.Номенклатура
|ГДЕ
| Продажи.КоличествоРасход > 1000
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Остатки.Номенклатура,
| ЕСТЬNULL(Продажи.КоличествоРасход, 0) КАК КоличествоРасход,
| Остатки.КоличествоОстаток,
| Остатки.КоличествоОстаток КАК Сортировка
|ПОМЕСТИТЬ ПоОстаткам
|ИЗ
| Остатки КАК Остатки
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Продажи КАК Продажи
| ПО Остатки.Номенклатура = Продажи.Номенклатура
|ГДЕ
| Продажи.КоличествоРасход < 100
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ПоПродажам.Номенклатура КАК Номенклатура,
| ПоПродажам.КоличествоРасход КАК КоличествоРасход,
| ПоПродажам.КоличествоОстаток КАК КоличествоОстаток,
| ПоПродажам.Сортировка КАК Сортировка
|ИЗ
| ПоПродажам КАК ПоПродажам
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ПоОстаткам.Номенклатура,
| ПоОстаткам.КоличествоРасход,
| ПоОстаткам.КоличествоОстаток,
| ПоОстаткам.Сортировка
|ИЗ
| ПоОстаткам КАК ПоОстаткам
|
|УПОРЯДОЧИТЬ ПО
| Сортировка
3.Подзапрос не нужен. Правильнее сделать следующее:
3.1.Сохраняем актуальные остатки номенклатуры (т.е. виртуальная таблица ОстаткиТоваровОстатки, без параметров) в временной таблице Остатки, индексируем по номенклатуре (единственный столбец выборки).
3.2.Отбираем из табличной части документа ПоступлениеНоменклатуры.Товары номенклатуру и дату (внутренне соединив её с временной таблицей остатки что-бы отбирать не по всем позициям а только те что есть в остатках), группируем по полю номенклатура – для даты используем агрегированную функцию максимум. Результат помещаем во временную таблицу ДатыПоступления, индексируем по номенклатуре.
3.3.Отбираем из табличной части документа ПоступлениеНоменклатуры.Товары реквизиты: номенклатура, контрагент и дату (внутренне соединие с временной талицей ДатыПоступления, условие номенклатура=номенклатура и дата=дата) ложим во временную таблицу НоменклатураСКонтрагентами.
3.4.Внутренне соединяем виртуаьную таблицу ЦеныНоменклатурыСрезПервых с Временной таблицей НоменклатураСКонтрагентами (связь по периоду и по номенклатуре). На выдачу из временной таблицы номенклатуру и контрагента, из регистра сведений – цену.
вместо 1000 читсать 100
И ещё вместо
УПОРЯДОЧИТЬ ПО Сортировка
читать
УПОРЯДОЧИТЬ ПО Сортировка УБЫВ
и ещё один момент: в последнем запросе так-же нужно в последнем запросе дополнительно отбирать ещё 1 столбец причем например так: для ВТ ПоПродажам он всегда =1, а для ВТ ПоОстаткам всегда = 2 и сортировать по этому столбцу в ASC а по столбцу сортировка DESC. Ну теперь уж точно всё. Возможно даже с некоторой долей оптимальности… надеюсь…
Поэтапное решение. Зачет!
В общем это конечно не всё, есть альтернативный вариант: не формировать 2 временных таблицы в запросах “ПоПродажам” и “ПоОстаткам” пакета запросов а одним запросом только в зависимости от величины остатка в поле сортировки ложить или величину продаж или величину остатка. Тогда получается на 1 запрос в пакете меньше, но тогда при сортировке сортируется не 2 упорядоченых по первому ключу индекса таблицы а 1 полностью не сортированная… но всё-же этот вариант должен отработать быстрее.
Задание выполнил.
Задача 1.
Для корректного решения задачи Виктору необходимо использовать в запросе внутреннее соединение:
<code>
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток,
ПродажиОбороты.КоличествоОборот
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ПО ОстаткиТоваровОстатки.Номенклатура = ПродажиОбороты.Номенклатура
</code>
Задача 2.
Для решения задачи используем пакетный запрос и временные таблицы:
<code>
// формируем таблицу продаж с данными по остаткам
ВЫБРАТЬ
ПродажиОбороты.Номенклатура,
ПродажиОбороты.КоличествоОборот КАК Продажа,
ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КАК Остаток
ПОМЕСТИТЬ Табл
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ПО ПродажиОбороты.Номенклатура = ОстаткиТоваровОстатки.Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
// формируем таблицу продаж более 100
ВЫБРАТЬ
Табл.Номенклатура,
Табл.Продажа КАК Продажа,
Табл.Остаток,
Табл.Продажа КАК ПолеСортировки,
1 КАК Приоритет
ПОМЕСТИТЬ ТаблБольше100
ИЗ
Табл КАК Табл
ГДЕ
Табл.Продажа > 100
;
////////////////////////////////////////////////////////////////////////////////
// формируем таблицу продаж до 100
ВЫБРАТЬ
Табл.Номенклатура,
Табл.Продажа,
Табл.Остаток,
Табл.Остаток КАК ПолеСортировки,
0 КАК Приоритет
ПОМЕСТИТЬ ТаблДо100
ИЗ
Табл КАК Табл
ГДЕ
Табл.Продажа <= 100
;
////////////////////////////////////////////////////////////////////////////////
// итоговый запрос
ВЫБРАТЬ
ТаблБольше100.Номенклатура,
ТаблБольше100.Продажа,
ТаблБольше100.Остаток,
ТаблБольше100.ПолеСортировки КАК ПолеСортировки,
ТаблБольше100.Приоритет КАК Приоритет
ИЗ
ТаблБольше100 КАК ТаблБольше100
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ТаблДо100.Номенклатура,
ТаблДо100.Продажа,
ТаблДо100.Остаток,
ТаблДо100.ПолеСортировки,
ТаблДо100.Приоритет
ИЗ
ТаблДо100 КАК ТаблДо100
УПОРЯДОЧИТЬ ПО
Приоритет УБЫВ,
ПолеСортировки УБЫВ
</code>
Задача 3.
Более оптимальным будет следующий запрос:
<code>
ВЫБРАТЬ РАЗЛИЧНЫЕ
ПоступлениеТоваровТовары.Номенклатура,
ПоступлениеТоваровТовары.Ссылка.Контрагент
ПОМЕСТИТЬ ТаблЗакупок
ИЗ
Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
ГДЕ
ПоступлениеТоваровТовары.Ссылка.Проведен
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток
ПОМЕСТИТЬ Остатки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки(
,
Номенклатура В
(ВЫБРАТЬ
ТаблЗакупок.Номенклатура
ИЗ
ТаблЗакупок КАК ТаблЗакупок)) КАК ОстаткиТоваровОстатки
ГДЕ
ОстаткиТоваровОстатки.КоличествоОстаток > 0
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Остатки.Номенклатура,
ТаблЗакупок.Контрагент,
Остатки.КоличествоОстаток,
ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена
ИЗ
Остатки КАК Остатки
ЛЕВОЕ СОЕДИНЕНИЕ ТаблЗакупок КАК ТаблЗакупок
ПО Остатки.Номенклатура = ТаблЗакупок.Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних
ПО Остатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
</code>
Задание1
Левое соединение заменила на внутреннее.
Задание2.
Соединяем таблицы ОстаткиТоваровОстатки и ПродажиОбороты. Соединение таблиц внутреннее. Выбираем поля номенклатура, КоличествоОборот, КоличествоОстаток и дополнительное поле для сортировки
ВЫБОР
КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100
ТОГДА ПродажиОбороты.КоличествоОборот
ИНАЧЕ 0
КОНЕЦ КАК Сортировка
Упорядочивание таблиц по двум полям
УПОРЯДОЧИТЬ ПО
Сортировка УБЫВ,
КоличествоОстаток УБЫВ
Задача 3.
Во временную таблицу Остатки помещаем остатки по номенклатуре из РегистрНакопления.ОстаткиТоваров.Остатки, индексируем по Номенклатуре.
Во временную таблицу Закупки помещаем поля Номенклатура, Контрагент из табличной части Документ.ПоступлениеТоваров.Товары с использованием опции РАЗЛИЧНЫЕ. Индексирование по Номенклатуре.
Соединяем две ВТ и РС ЦеныНоменклатуры левым соединением по номенклатуре. В параметрах РС накладываем условие, что номенклатура входит во ВТ Остатки.
ДЗ выполнено
1. Вместо левого соединения нужно использовать внутреннее, при этом условие “ПродажиОбороты.КоличествоОборот ЕСТЬ НЕ NULL” можно убрать.
2. Через ОБЪЕДИНИТЬ ВСЕ выполнил два запроса, первый к ВТ Продажи.Обороты, второй к ВТ ОстаткиТоваров.Остатки. Объединение таблиц поместил по вложенный запрос. Сгруппировал по номенклатуре полученные данные и добавил еще одно поле для группировки:
ВЫБОР
КОГДА СУММА(ВложенныйЗапрос.КоличествоПродано) > 100
ТОГДА СУММА(ВложенныйЗапрос.КоличествоПродано)
ИНАЧЕ СУММА(ВложенныйЗапрос.КоличествоНаОстатке)
КОНЕЦ КАК ПолеДляСортировки
Полученный результат сохранил по временную таблицу. Далее сделал выборку данных из этой таблицы с сортировкой по ПолеДляСортировки УБЫВ
3. Пусть Виктор С. не обижается, но мне показалось, что проще переписать такой чудесный запрос, чем его оптимизировать :)
Итак, выполнил запрос к таблице остатков, выбрав номенклатуру, остаток которой больше нуля. Полученные данные поместил во временную таблицу ВТ_Остатки, индексировал по полю Номенклатура.
Затем выполнил запрос к таблице ПоступлениеТоваровИУслуг.Товары у проведенных документов, выбрав поля контрагент и номенклатура. С полученными записями сделал внутреннее соединение по полю номенклатура с ВТ_Остатки, тем самым отсек все товары, которых нет сейчас на складе. Тут же сделал левое соединение с регистром ЦеныНоменклатуры по полю Номенклатура. Выбираемое поле ЦеныНоменклатурыСрезПоследних.Цена обернул в условие ЕСТЬNULL.
ДЗ выполнил.
Задача 1. Заменил левое соединение на внутреннее, и ЕСТЬ НЕ NULL на >0.
Задача 2. В ВТ помещается выборка по номенклатуре, КоличествоОборот, КоличествоОстаток из РН Остатки и ПродажиОбороты, а также дополнительное поле ПоКоличеству (Выбор КоличествоОборот > 100 Тогда КоличествоОборот Иначе 0). Соединение регистров внутреннее – по номенклатуре и КоличествоОстаток > 0. Далее выборка из ВТ с упорядочиванием по ПоКоличеству УБЫВ, Остаток УБЫВ.
Задача 3. Т.к. по заданию в выборке должны присутствовать только те товары, которые есть на складе, то в ВТ (Остатки) из РН Остатки выгружается номенклатура с КоличествоОстаток>0. Индексирование – по номенклатуре. Далее во вторую ВТ (Товары) выгружается связка Номенклатура-Ссылка.Контрагент из ТЧ ПоступлениеТоваровТовары,
с проверкой на проведенность документа и что Ссылка.Контрагент не пустая ссылка. Индексирование также по номенклатуре.
Запросом из двух ВТ и РС ЦеныСрезПоследних (для него в параметрах – условие, что Номенклатура входит в ВТ Остатки) получаю искомый результат.
Связь – левое соединение ВТ Остатки с ВТ Товары и РС Цены по номенклатуре.
Задание 1.
У Виктора С. главная ошибка это левое соединение, которое вернет все записи таблицы ОстаткиТоваровОстатки и там где не найдено соответствие по его условию и будет КоличествоОборот NULL. А его попытка наложить условие на НЕ NULL для поля виртуальной таблицы ПродажиОбороты.КоличествоОборот бессмыслено, т.к. если найдено соответствие по номенклатуре двух таблиц, то условие соединения по полю таблицы (ПродажиОбороты.КоличествоОборот Есть Не NULL) вернет всегда ИСТИНА .
Данное задание решаеться просто внутренним соединением по полю Номенклатура двух таблиц (причем, в таблицу оборотов желательно/обязательно передать товары имеющиеся в наличии) . Или же, если следовать логики Виктора, левым соединение по номенклатуре, но его условие (ПродажиОбороты.КоличествоОборот Есть Не NULL) в этом случаи нужно использовать в секции ГДЕ,.
Задание 2.
Т.к. анализируем остатки на конкретную дату, а продажи за весь период то соединение таблиц полное. Для сортировки определяем дополнительное вычисляемое поле.
ВЫБРАТЬ
ЕСТЬNULL(ОстаткиТоваровОстатки.Номенклатура, ПродажиОбороты.Номенклатура) КАК Товар,
ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) КАК Количество,
ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КАК Остаток,
ВЫБОР
КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100
ТОГДА ПродажиОбороты.КоличествоОборот
ИНАЧЕ ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0)
КОНЕЦ КАК ПолеСортировки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки(&Период, ) КАК ОстаткиТоваровОстатки
ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ПО ОстаткиТоваровОстатки.Номенклатура = ПродажиОбороты.Номенклатура
УПОРЯДОЧИТЬ ПО
ПолеСортировки УБЫВ
Задание 3.
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура,
ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена
ПОМЕСТИТЬ НоменклатураЦены
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних
ПО ОстаткиТоваровОстатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ОстаткиТоваровОбороты.Номенклатура,
ОстаткиТоваровОбороты.Регистратор.Контрагент КАК Контрагент
ПОМЕСТИТЬ НоменклатураКонтрагенты
ИЗ
РегистрНакопления.ОстаткиТоваров.Обороты(
,
,
Регистратор,
Номенклатура В
(ВЫБРАТЬ
НоменклатураЦены.Номенклатура
ИЗ
НоменклатураЦены КАК НоменклатураЦены)) КАК ОстаткиТоваровОбороты
ГДЕ
ТИПЗНАЧЕНИЯ(ОстаткиТоваровОбороты.Регистратор) = ТИП(Документ.ПоступлениеТоваровИУслуг)
СГРУППИРОВАТЬ ПО
ОстаткиТоваровОбороты.Номенклатура,
ОстаткиТоваровОбороты.Регистратор.Контрагент
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
НоменклатураЦены.Номенклатура,
НоменклатураЦены.Цена,
НоменклатураКонтрагенты.Контрагент
ИЗ
НоменклатураЦены КАК НоменклатураЦены
ВНУТРЕННЕЕ СОЕДИНЕНИЕ НоменклатураКонтрагенты КАК НоменклатураКонтрагенты
ПО НоменклатураЦены.Номенклатура = НоменклатураКонтрагенты.Номенклатура
Является ли в моем запросе обращение ОстаткиТоваровОбороты.Регистратор.Контрагент более оптимальным (разворот по периоду Регистратор, регистратор – составной, Контрагент – разыменование регистратора, плюс условие на тип регистратора, ведь даже приход могут делать ВводОстатков и ВозвратыПоставщику), чем напрямую обращение к таблице документа ПоступлениеТоваров – вопрос? Наверное, все таки, да.
Нет, ваше разыменование будет работать неэффективно. Поскольку создаст левые соединения со всеми видами документов, являющимися регистраторами данного регистра.
Для более оптимального решения задачи можно использовать функцию Выразить() и привести регистратор к конкретному типу данных.
Задание выполнил!
Задачу 1 решил заменив левое соединение в запросе на внутреннее.
Задача 2. Для решения составил запрос, где использую доп. поле “ПолеСортировки” для настройки заданного варианта сортировки:
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура КАК Номенклатура,
ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток,
ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) КАК КоличествоПродажи,
ВЫБОР
КОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) > 100
ТОГДА ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0)
ИНАЧЕ ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0)
КОНЕЦ КАК ПолеСортировки
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(, , Период, ) КАК ПродажиОбороты
ПО ОстаткиТоваровОстатки.Номенклатура = ПродажиОбороты.Номенклатура
УПОРЯДОЧИТЬ ПО
ПолеСортировки УБЫВ
Задача 3. Оптимизация запроса заключается в создании пакета запросов с более оптимальными связями:
ВЫБРАТЬ РАЗЛИЧНЫЕ
ПоступлениеТоваровТовары.Номенклатура КАК Номенклатура,
ПоступлениеТоваровТовары.Ссылка.Контрагент КАК Контрагент
ПОМЕСТИТЬ ТоварыПоставщики
ИЗ
Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
ГДЕ
ПоступлениеТоваровТовары.Ссылка.Проведен
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
///////////////////////////////////////////////
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура КАК Номенклатура,
ТоварыПоставщики.Контрагент
ПОМЕСТИТЬ ОстаткиПоставщики
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТоварыПоставщики КАК ТоварыПоставщики
ПО ОстаткиТоваровОстатки.Номенклатура = ТоварыПоставщики.Номенклатура
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
///////////////////////////////////////////
ВЫБРАТЬ
ОстаткиПоставщики.Номенклатура КАК Номенклатура,
ОстаткиПоставщики.Контрагент,
ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена
ИЗ
ОстаткиПоставщики КАК ОстаткиПоставщики
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних
ПО ОстаткиПоставщики.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
УПОРЯДОЧИТЬ ПО
Цена УБЫВ,
Номенклатура
Задача №1
Ошибка здесь в соединении запросов. Для получения тех записей которые есть на остатках и продавались необходимо использовать внутренние соединение двух таблиц.
Задача №2
Задача решается путем объединения двух запросов, запросы одинаковые отличаются только условием в первом запросе в секции где используется условие вида ПродажиОбороты.КоличествоОборот > 100, во втором наоборот «<=».
Поскольку необходимо получать данные и о продажах и об остатках, запрос представляет собой полное соединение двух виртуальных таблиц Продажи.Обороты и ОстаткиТоваров.Остатки. Для реализации сортировки используется еще одно поле, которое в первом запросе заполняется значением объема продаж, а во втором запросе остатком товара. Поскольку сортировка результатов запроса происходит после их объединения, то сортировка по этому полю дает нужный результат.
Задача №3
Следует отдать вам должное Евгений, пожалуй, хуже запроса решающего эту задачу придумать сложно. :)
Задача решается достаточно просто, основной таблицей является виртуальная таблица остатков, к которой левым соединением присоединяются записи регистров сведений цены номенклатуры срез последних и ТЧ «Товары» документа «Поступление товаров» пи этом накладывается условие на контрагента НЕ NULL в секции ГДЕ и убираются дубли с помощью опции РАЗЛИЧНЫЕ.
Подумал, как можно оптимизировать и изменил запрос, поместив сначала остатки во временную таблицу, остальное оставил без изменений.