Имя: Пароль:
1C
1С v8
Как избавиться от запроса в цикле
0 МешочекЗнаний
 
26.03.16
17:59
Добрый вечер.

Привожу сфеерический пример в вакууме.

Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    ПоступлениеТоваров.ДатаПоступления,
        |    ПоступлениеТоваров.Номенклатура
        |ИЗ
        |    РегистрСведений.ПоступлениеТоваров КАК ПоступлениеТоваров";
    
    РезультатЗапроса = Запрос.Выполнить();    
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл    
        Запрос2 = Новый Запрос;
        Запрос2.Текст =
        "ВЫБРАТЬ
        |    ЦеныНоменклатурыСрезПоследних.Номенклатура,
        |    ЦеныНоменклатурыСрезПоследних.Цена
        |ИЗ
        |    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, Номенклатура = &Номенклатура) КАК ЦеныНоменклатурыСрезПоследних";
        
        Запрос2.УстановитьПараметр("Дата", ВыборкаДетальныеЗаписи.ДатаПоступления);
        Запрос2.УстановитьПараметр("Номенклатура", ВыборкаДетальныеЗаписи.Номенклатура);
        
        РезультатЗапроса2 = Запрос2.Выполнить();
        
        ВыборкаДетальныеЗаписи2 = РезультатЗапроса2.Выбрать();
        
        Пока ВыборкаДетальныеЗаписи2.Следующий() Цикл
            Сообщить("У номенклатуры " + ВыборкаДетальныеЗаписи.Номенклатура + " " + ВыборкаДетальныеЗаписи.ДатаПоступления + " была цена: " + ВыборкаДетальныеЗаписи2.Цена);
        КонецЦикла;
    КонецЦикла;

Как избавиться от запроса в цикле?
1 poligraf
 
26.03.16
18:01
(0) гуглить "срез последних на каждую дату"
2 PR третий
 
26.03.16
18:17
(0) Мне коллега предлагал такую задачу давать на собеседовании.
Я отказался, слишком простая и слишком узко техническая, непоказательная.
3 МешочекЗнаний
 
26.03.16
18:20
(2) Да я самообучением сижу занимаюсь, сам себе задачи придумываю. Задачу то себе поставил, а как сделать не додумался.
4 Garykom
 
гуру
26.03.16
18:22
(3) одним запросом то сделай через левое соединение
http://forum.infostart.ru/forum26/topic70668/
5 МешочекЗнаний
 
26.03.16
20:15
(1)(3) Спасибо большое! Всё получилось.

Но теперь у меня ещё вопрос - один запрос через левое соединение работает медленнее, чем временные непроиндексированные таблицы.

Размер таблиц 20 000 в одном РС, 20 000 в другом РС.
Результат: http://s018.radikal.ru/i523/1603/ad/5dc54bf7dc3b.png

Запрос 1 (медленнее) - один запрос

ВЫБРАТЬ
    ВложенныйЗапрос.ДатаПоступления КАК ДатаПоступления,
    ВложенныйЗапрос.Номенклатура,
    ЦеныНоменклатуры.Цена
ИЗ
    (ВЫБРАТЬ
        ПоступлениеТоваров.Номенклатура КАК Номенклатура,
        ПоступлениеТоваров.ДатаПоступления КАК ДатаПоступления,
        МАКСИМУМ(ЦеныНоменклатуры.Период) КАК Период
    ИЗ
        РегистрСведений.ПоступлениеТоваров КАК ПоступлениеТоваров
            ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
            ПО ПоступлениеТоваров.Номенклатура = ЦеныНоменклатуры.Номенклатура
                И (ЦеныНоменклатуры.Период <= ПоступлениеТоваров.ДатаПоступления)
    
    СГРУППИРОВАТЬ ПО
        ПоступлениеТоваров.Номенклатура,
        ПоступлениеТоваров.ДатаПоступления) КАК ВложенныйЗапрос
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
        ПО ВложенныйЗапрос.Период = ЦеныНоменклатуры.Период
            И ВложенныйЗапрос.Номенклатура = ЦеныНоменклатуры.Номенклатура

УПОРЯДОЧИТЬ ПО
    ДатаПоступления

Запрос 2 (быстрее) - через временные таблицы

ВЫБРАТЬ
    ПоступлениеТоваров.ДатаПоступления,
    ПоступлениеТоваров.Номенклатура
ПОМЕСТИТЬ ВТ_Номенклатура
ИЗ
    РегистрСведений.ПоступлениеТоваров КАК ПоступлениеТоваров
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Номенклатура.ДатаПоступления КАК ДатаПоступления,
    ВТ_Номенклатура.Номенклатура,
    МАКСИМУМ(ЦеныНоменклатуры.Период) КАК Период
ПОМЕСТИТЬ ВТ_Периоды
ИЗ
    РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Номенклатура КАК ВТ_Номенклатура
        ПО ЦеныНоменклатуры.Номенклатура = ВТ_Номенклатура.Номенклатура
            И ЦеныНоменклатуры.Период <= ВТ_Номенклатура.ДатаПоступления

СГРУППИРОВАТЬ ПО
    ВТ_Номенклатура.ДатаПоступления,
    ВТ_Номенклатура.Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Номенклатура.ДатаПоступления КАК ДатаПоступления,
    ВТ_Номенклатура.Номенклатура,
    ВложенныйЗапрос.Цена
ИЗ
    ВТ_Номенклатура КАК ВТ_Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
            ВТ_Периоды.ДатаПоступления КАК ДатаПоступления,
            ЦеныНоменклатуры.Номенклатура КАК Номенклатура,
            ЦеныНоменклатуры.Цена КАК Цена
        ИЗ
            ВТ_Периоды КАК ВТ_Периоды
                ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
                ПО ВТ_Периоды.Номенклатура = ЦеныНоменклатуры.Номенклатура
                    И ВТ_Периоды.Период = ЦеныНоменклатуры.Период) КАК ВложенныйЗапрос
        ПО ВТ_Номенклатура.Номенклатура = ВложенныйЗапрос.Номенклатура
            И ВТ_Номенклатура.ДатаПоступления = ВложенныйЗапрос.ДатаПоступления

УПОРЯДОЧИТЬ ПО
    ДатаПоступления
6 hhhh
 
26.03.16
20:54
(5) когда будет 20млн. записей, тогда начинай беспокоиться. А 20000 - это смешно, даже ниже уровня детского сада, вообще не парься.