Опять эти запросы...

Публикация № 427180

Разработка - Практика программирования

Запрос остатки срез остатков срез цен периоды

В статье описываются варианты построения выборки диапазона чисел или дат с помощью запроса. Рассматривается модифицированный вариант получения запросом среза остатков по регистру накопления или цен по регистру сведений на разные даты и производится сравнительный тест вариантов реализаций. Демонстрируется вариант реализации генерации нумерованных комбинаций свойств товара в запросе, по переданному набору перечня товара и его свойств.

1. Генерация диапазона чисел запросом.

Данный метод уже не раз был описан. Повторюсь с некоторыми своими комментариями.

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

ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1;

ВЫБРАТЬ ВТ0.Ч + ВТ1.Ч*2 + ВТ2.Ч*4 + ВТ3.Ч*8 КАК Число
ИЗ ВТ КАК ВТ0, ВТ КАК ВТ1, ВТ КАК ВТ2, ВТ КАК ВТ3

В запросе выбираем числа 0,1 и помещаем во временную таблицу ВТ. Последующее соединение-сочетание таких таблиц образует необходимую выборку. Диапазон чисел, который сгенерирует такой запрос, будет равняться M в степени N, где M - количество чисел в системе счисления, N - количество соединяемых таблиц. В нашем примере имеем систему счисления с двумя числами и  базовая таблица соединяется "сама с собой" 4 раза, поэтому результат получим в 16 чисел. Для получения большего диапазона чисел необходимо увеличивать количество соединений базовой таблицы, или же изменить систему счисления. 

Т.к. многие привыкли работать в основном с десятичной системой счисления, используем ее и получим следующий запрос:

ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000 КАК Число
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3

Этот запрос позволяет сформировать выборку чисел от 0 до 9999. Для увеличения диапазона выбранных чисел увеличиваем количество соединений базовой таблицы.

2. Генерация диапазона дат запросом в заданном периоде.

Для получения выборки различных дат многие используют периодические регистры сведений из конфигурации.

Можно, например, получить выборку дат из регистра сведений "Курсы валют":

 

ВЫБРАТЬ РАЗЛИЧНЫЕ
КурсыВалют.Период КАК Дата
ИЗ  РегистрСведений.КурсыВалют КАК КурсыВалют
ГДЕ КурсыВалют.Период МЕЖДУ &НачалоПериода И &КонецПериода


или же получить выборку периодов из регламентированного календаря (если такой есть в конфигурации):

 

ВЫБРАТЬ Рег.ДатаКалендаря КАК Дата
ИЗ РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Рег
ГДЕ Рег.ДатаКалендаря МЕЖДУ &НачалоПериода И &КонецПериода


Однако, при получении такой выборки данных для последующих расчетов, разработчик должен быть уверен, что эти данные в регистрах есть. В случае, если в информационной базе не внесены курсы валют за все дни или же не заполнен регламентированный производственный календарь, он не получит необходимую выборку данных.

Используя предыдущий метод генерации набора чисел, можно легко сформировать запрос-выборку периодов без использования регистров сведений.

 

ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода,День),День,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) КАК День
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3
ГДЕ ДОБАВИТЬКДАТЕ(&НачалоПериода,День,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) <= НАЧАЛОПЕРИОДА(&КонецПериода,День)


Этот запрос позволяет сделать выборку всех дней с НачалоПериода по КонецПериода. Максимальное количество дней для этого запроса составляет 10000 (27 лет).

Такой запрос легко трансформируется в выборку секунд, минут, часов, лет или кварталов путем замены параметра "День" на "Секунда","Час","Минута","Год" или "Квартал". Выборка разных кварталов, например, будет выглядеть так:

 

ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода,Квартал),Квартал,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) КАК Квартал
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3
ГДЕ ДОБАВИТЬКДАТЕ(&НачалоПериода,Квартал,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) <= НАЧАЛОПЕРИОДА(&КонецПериода,Квартал)


Важно помнить, что базовый запрос выборки чисел имеет ограничение в 10000 записей. Если по поставленной задаче выборка периодов может захватывать больше диапазон записей, необходимо расширять выборку чисел путем добавления дополнительного соединение базовой таблицы чисел

3. Остатки товаров и срезы последних запросом на каждый день.

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

Например в теме //infostart.ru/public/306536/ пользователем ildarovich был предложен следующий вариант получения остатков товаров на каждый день:

ВЫБРАТЬ РАЗЛИЧНЫЕ
    КурсыВалют.Период
ПОМЕСТИТЬ Дни
ИЗ
    РегистрСведений.КурсыВалют КАК КурсыВалют
ГДЕ
    КурсыВалют.Период МЕЖДУ &НачалоПериода И &КонецПериода
;

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

СГРУППИРОВАТЬ ПО
    Движения.Номенклатура,
    ДНИ.Период

По моему личному опыту формирование запросов с выборкой данных из таблицы базы данных в сочетании с конструкцией полного соединения и последующей группировки данных в ряде случев может привести к замедлению выполнения запроса.

Кто выполнял оптимизацию запроса списания по партиям в УТП, УПП, возможно, сталкивались с проблемой, когда этот запрос выполняется очень долго. В моей практике у некоторых клиентов этот запрос иногда даже "зависал" или порождал длительную транзакцию.

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

Да, понимаю, чтение этих данных будет требовать дополнительных ресурсов сервера баз данных на создание и размещение временной таблицы, однако с другой стороны у нас еще есть такая штука, как РЛС. На первый взгляд, базовый простой запрос в сочетании с существующими ограничениями на уровне записей может породить насколько громадный запрос обращения к серверу баз данных, что выполнение его может быть значительно по времени. Ну и если взять во внимание, что не все пользователи-клиенты производят регламентные операции обновления статистики, реиндексации и пр. на сервере баз данных, то такие запросы у них могут быть проблемным местом реализации.

Ближе к делу... Эксперимент

Беру предложенный вариант получения дневных конечных остатков по товарам на складах пользователя ildarovich и делаю из него следующий запрос для тестирования:

ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода,День),День,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) КАК Период
ПОМЕСТИТЬ Дни
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3
ГДЕ ДОБАВИТЬКДАТЕ(&НачалоПериода,День,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) <= НАЧАЛОПЕРИОДА(&КонецПериода,День);

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

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

ВЫБРАТЬ СУММА(ВТИтог.КоличествоКонечныйОстаток) КАК КоличествоКонечныйОстаток
ИЗ ВТИтог КАК ВТИтог

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

Для сравнения использую следующий запрос получения остатков на конец дня:

ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода,День),День,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) КАК Период
ПОМЕСТИТЬ Дни
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3
ГДЕ ДОБАВИТЬКДАТЕ(&НачалоПериода,День,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) <= НАЧАЛОПЕРИОДА(&КонецПериода,День);

ВЫБРАТЬ
    Движения.Номенклатура,
    Движения.Период,
    Движения.КоличествоКонечныйОстаток
ПОМЕСТИТЬ ВТД
ИЗ
    РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, , ) КАК Движения

ИНДЕКСИРОВАТЬ ПО
    Движения.Номенклатура,
    Движения.Период;

ВЫБРАТЬ
    ВН.Номенклатура,
    ВН.Период,
    ЕСТЬNULL(ВТД.КоличествоКонечныйОстаток, 0) КАК КоличествоКонечныйОстаток
ПОМЕСТИТЬ ВТИтог
ИЗ
    (ВЫБРАТЬ РАЗЛИЧНЫЕ
        Дни.Период КАК Период,
        ВТД.Номенклатура КАК Номенклатура
    ИЗ
        Дни КАК Дни,
        ВТД КАК ВТД) КАК ВН
        ЛЕВОЕ СОЕДИНЕНИЕ ВТД КАК ВТД
        ПО ВН.Номенклатура = ВТД.Номенклатура
            И ВН.Период >= ВТД.Период
            И (ВТД.Период В (ВЫБРАТЬ МАКСИМУМ(ВП.Период)
                ИЗ ВТД КАК ВП
                ГДЕ ВП.Номенклатура = ВТД.Номенклатура
                    И ВН.Период >= ВП.Период));

ВЫБРАТЬ СУММА(ВТИтог.КоличествоКонечныйОстаток) КАК КоличествоКонечныйОстаток
ИЗ  ВТИтог КАК ВТИтог

Оба запроса выполняю в консоли запросов 10 раз и фиксирую время выполнения

Замер Запрос 1 Запрос 2
1 4,609 4,297
2 4,531 4,297
3 4,563 4,328
4 4,609 4,297
5 4,703 4,313
6 4,578 4,454
7 4,469 4,297
8 4,484 4,313
9 4,515 4,281
10 4,703 4,297

Среднее,с.

4,5764 4,3174

Итоги тестирования показывают небольшой прирост производительности, чуть больше 5%. Однако эти замеры производились под полными правами. Можете проверить результаты под пользователем с ограниченной учетной записью на регистр "ТоварыНаСкладах", думаю, прирост производительности предлагаемого запроса будет еще выше.

Дополнительным преимуществом предлагаемого варианта запроса есть то, что мы уже имеем выборку проиндексированных данных по товарам на складах. Часто сложные отчеты предполагают срезы остатков по дням из разных регистров и наличие такой выборки упросит дальнейшее формирование логики запроса и это в сочетании хоть с небольшим но приростом производительности.

Рассмотрим вариант применения такой реализации в запросе с регистром сведений.

За базу возьмем вариант получения цен номенклатуры на дату продажи товара предложенный в теме //infostart.ru/public/77568/ пользователем _also . Его запрос выглядит так:

 

ВЫБРАТЬ
    ПродажиОбороты.Период КАК Дата,
    ПродажиОбороты.Контрагент КАК Контрагент,
    ПродажиОбороты.Номенклатура КАК Номенклатура,
    СУММА(ПродажиОбороты.КоличествоОборот) КАК Количество,
    СУММА(ПродажиОбороты.СтоимостьОборот) КАК Стоимость
ПОМЕСТИТЬ втБезЦены
ИЗ
    РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК ПродажиОбороты

СГРУППИРОВАТЬ ПО
    ПродажиОбороты.Период,
    ПродажиОбороты.Контрагент,
    ПродажиОбороты.Номенклатура

ИНДЕКСИРОВАТЬ ПО
    Номенклатура,
    Дата,
    Контрагент
;

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

СГРУППИРОВАТЬ ПО
    втБезЦены.Дата,
    втБезЦены.Контрагент,
    втБезЦены.Номенклатура,
    втБезЦены.Количество,
    втБезЦены.Стоимость

ИНДЕКСИРОВАТЬ ПО
    Номенклатура,
    Дата,
    Контрагент,
    Период
;

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


Если смысл данного запроса состоял в получении всей выборки продаж за период и среза цен на дату продажи, то исправим две логические ошибки в запросе. Первая ошибка: в запросе итоговая таблица фильтруется по типу цен. В случае, если для указанного типа цен не было установок цен номенклатуры но были продажи, эти продажи будут отсеяны. Вторая ошибка: цены номенклатуры регистрируются по позиции регистратора. В случае, когда на одну и ту-же дату разными регистраторами будет установлена отдельная цена, произойдет задвоение данных в базовой выборке продаж. Исправим этот запрос и получим первый запрос для тестирования:

ВЫБРАТЬ
    ПродажиОбороты.Период КАК Дата,
    ПродажиОбороты.Контрагент КАК Контрагент,
    ПродажиОбороты.Номенклатура КАК Номенклатура,
    СУММА(ПродажиОбороты.КоличествоОборот) КАК Количество,
    СУММА(ПродажиОбороты.СтоимостьОборот) КАК Стоимость
ПОМЕСТИТЬ втБезЦены
ИЗ
    РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК ПродажиОбороты

СГРУППИРОВАТЬ ПО
    ПродажиОбороты.Период,
    ПродажиОбороты.Контрагент,
    ПродажиОбороты.Номенклатура

ИНДЕКСИРОВАТЬ ПО
    Номенклатура,
    Дата;

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

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

Мой запрос в данной реализации выглядел бы так:

ВЫБРАТЬ
    Продажи.Дата,
    Продажи.Контрагент,
    Продажи.Номенклатура,
    Продажи.Количество,
    Продажи.Стоимость,
    ЕСТЬNULL(Цены.Цена, 0) КАК Цена
ИЗ
    (ВЫБРАТЬ
        ПродажиОбороты.Период КАК Дата,
        ПродажиОбороты.Контрагент КАК Контрагент,
        ПродажиОбороты.Номенклатура КАК Номенклатура,
        СУММА(ПродажиОбороты.КоличествоОборот) КАК Количество,
        СУММА(ПродажиОбороты.СтоимостьОборот) КАК Стоимость
    ИЗ
        РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК ПродажиОбороты

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

 

Выполняю 10 раз подряд каждый запрос и фиксирую время выполнения:

Замер Запрос 1 Запрос 2
1 0,875 0,313
2 0,844 0,265
3 0,844 0,266
4 0,843 0,297
5 0,844 0,282
6 0,859 0,281
7 0,844 0,297
8 0,843 0,281
9 0,984 0,283
10 0,844 0,297
Среднее, с. 0,8624 0,2862

Время выполнения предложенного мною запроса в среднем на 66% меньше. Интересно, какие результаты получатся у других пользователях на своем "железе".

4. Генерация нумерованных комбинаций свойств товара в запросе

На создание запроса, который для указанного перечня товара и набора свойств сгенерирует все возможные комбинации из этих свойств,  подтолкнула тема //infostart.ru/public/295343/ . Интересная задачка для разминки серого вещества.

Дабы не тратить уйму времени на универсальный запрос, оговорим, что в исходных данных может быть только два вида свойств. Ну, и чтобы запрос не был совсем детским, добавим изюминку - необходимо пронумеровать созданные пары свойств в пределах каждого товара.

К примеру, имеем мы на входе перечень товара с указанием их свойств:

Товар Свойство Значение свойства
Товар А Материал обшивки Сталь
Товар А Материал обшивки Алюминий
Товар А Материал обшивки Пластмасса
Товар А Материал основания Сталь
Товар А Материал основания Алюминий
Товар Б Материал обшивки Сталь
Товар Б Материал обшивки Алюминий
Товар Б Материал основания Алюминий
Товар Б Материал основания Сталь

Выберем эти данные запросом и поместим во временную таблицу ВТ, эта таблица и будет исходными данными для запроса:

ВЫБРАТЬ "Товар А" КАК Товар, "Материал обшивки" КАК Свойство, "Сталь" КАК Значение
ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар А", "Материал обшивки"   ,"Алюминий"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар А", "Материал обшивки"   ,"Пластмасса"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар А", "Материал основания" ,"Сталь"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар А", "Материал основания" ,"Алюминий"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар Б", "Материал обшивки"   ,"Сталь"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар Б", "Материал обшивки"   ,"Алюминий"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар Б", "Материал основания" ,"Алюминий"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар Б", "Материал основания" ,"Сталь";

Далее выполним следующую запрос:

ВЫБРАТЬ
   
ВТ1.Товар КАК Товар,
   
ВЫБОР
        КОГДА
ВТ1.Свойство > ВТ2.Свойство
            ТОГДА КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ4.Значение) * МАКСИМУМ(Ит.Итог) + КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ3.Значение)
       
ИНАЧЕ КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ3.Значение) * МАКСИМУМ(Ит.Итог) + КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ4.Значение)
   
КОНЕЦ +1 КАК Вариант,
   
ВТ1.Свойство КАК Свойство,
   
ВТ1.Значение
ИЗ
   
ВТ КАК ВТ1
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ КАК ВТ3
        ПО ВТ1.Товар = ВТ3.Товар
            И ВТ1.Свойство = ВТ3.Свойство
            И ВТ1.Значение > ВТ3.Значение,
   
ВТ КАК ВТ2
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ КАК ВТ4
        ПО ВТ2.Товар = ВТ4.Товар
            И ВТ2.Свойство = ВТ4.Свойство
            И ВТ2.Значение > ВТ4.Значение,
    (ВЫБРАТЬ
И2.Товар КАК Товар, МАКСИМУМ(И2.Итог) КАК Итог
        ИЗ (ВЫБРАТЬ И1.Товар КАК Товар, КОЛИЧЕСТВО(РАЗЛИЧНЫЕ И1.Значение) КАК Итог
            ИЗ ВТ КАК И1
            СГРУППИРОВАТЬ ПО
               
И1.Товар, И1.Свойство) КАК И2
    СГРУППИРОВАТЬ ПО И2.Товар) КАК Ит
ГДЕ
   
ВТ1.Товар = ВТ2.Товар
    И ВТ1.Товар = Ит.Товар
    И ВТ1.Свойство <> ВТ2.Свойство
СГРУППИРОВАТЬ ПО
   
ВТ1.Товар,
   
ВТ1.Свойство,
   
ВТ1.Значение,
   
ВТ2.Свойство,
   
ВТ2.Значение
УПОРЯДОЧИТЬ ПО
   
Товар,Вариант, Свойство

И получим выборку товара с перечнем пронумерованных комбинаций свойств.

 

Товар Вариант Свойство Значение
Товар А 1 Материал обшивки Алюминий
Товар А 1 Материал основания Алюминий
Товар А 2 Материал обшивки Алюминий
Товар А 2 Материал основания Сталь
Товар А 4 Материал обшивки Пластмасса
Товар А 4 Материал основания Алюминий
Товар А 5 Материал обшивки Пластмасса
Товар А 5 Материал основания Сталь
Товар А 7 Материал обшивки Сталь
Товар А 7 Материал основания Алюминий
Товар А 8 Материал обшивки Сталь
Товар А 8 Материал основания Сталь
Товар Б 1 Материал обшивки Алюминий
Товар Б 1 Материал основания Алюминий
Товар Б 2 Материал обшивки Алюминий
Товар Б 2 Материал основания Сталь
Товар Б 3 Материал обшивки Сталь
Товар Б 3 Материал основания Алюминий
Товар Б 4 Материал обшивки Сталь
Товар Б 4 Материал основания Сталь

В двух словах, как работает запрос. Соедиение базовой таблицы товара смой с собой по товару и различным свойствам дает нам ведущую выборку - все сочетания свойств. Ведущая выборка образуется из ВТ1 и ВТ2. Дополнительные соединение к этим двум таблицам базовой таблицы товара ВТ3 И ВТ4 с проверкой на значения свойств дает возможность накапивать  в итоговой выборке нумерацию сочетаний свойств зеркально по данным таблицы ВТ1 и ВТ2. Таблица Итог необходима для определения максимального количества различных значений свойств для каждого товара, сочетание этого значения с накопительными данными по двум зеркальным веткам накопления дадут итоговый вариант сочетания свойств товара. 

На вход запроса можно подавать различное количество свойств и товаров, главное, чтобы видов свойств было только 2 в пределах одного товара.

5. Определение интервалов в запросе.

В продолжения раздела 3 статьи хотелбы привести еще один сравнительный эксперимент. Эксперимент будет заключаться в сравнительном анализе потраченного времени на построение интервалов в запросе двумя методами. Будем сравнивать скорость выполнения запроса с группировкой и запроса с паралельной фильтрующей выборкой.

Первый запрос:

ВЫБРАТЬ
   
Т1.Ч КАК НачалоИнтервала,
   
МИНИМУМ(Т2.Ч) КАК КонецИнтервала
ПОМЕСТИТЬ Темп
ИЗ
   
БазоваяТаблица КАК Т1
      ВНУТРЕННЕЕ СОЕДИНЕНИЕ БазоваяТаблица КАК Т2
      ПО Т1.Ч < Т2.Ч

СГРУППИРОВАТЬ ПО Т1.Ч;

УНИЧТОЖИТЬ Темп

Второй запрос:

ВЫБРАТЬ РАЗЛИЧНЫЕ
   
Т1.Ч КАК НачалоИнтервала,
   
Т2.Ч КАК КонецИнтервала
ПОМЕСТИТЬ Темп
ИЗ
   
БазоваяТаблица КАК Т1
     ВНУТРЕННЕЕ СОЕДИНЕНИЕ БазоваяТаблица КАК Т2
     ПО Т1.Ч < Т2.Ч
        И (Т2.Ч В
           
(ВЫБРАТЬ МИНИМУМ(ВНЗ.Ч)
             ИЗ
БазоваяТаблица КАК ВНЗ
             ГДЕ Т1.Ч < ВНЗ.Ч));

УНИЧТОЖИТЬ Темп

Второй запрос построен мною по тому же принципу, что запрос  в  разделе 3 статьи.

Для тестирования я написал обработку которая сформирует N-индексированных временных таблиц определенного размера и выполнит тестовый замер времени выполнения первого и второго запроса. 

В обработке необходимо задать количество блоков данных - временных таблиц, прирост блока данных таблицы и сформировать временные таблицы. После формирования можно запускать тестирование.

Обработка производит поочерёдное выполнение правого и левого запроса с выборкой данных из каждой таблицы. Выполнение запросов производится по 5 раз по каждой временной таблице и выбирается наименьшее время выполнения каждого запроса - дабы немного исключить возможные временных всплески нагрузок на сервере. 

Тестирование производил на стареньком двухпроцессорном Supermicro-сервере на 8 ядрах Xeon 2.3 ГГц с 6 ГГб оперативной памяти и бюджетным  SSD. Сервер баз данных MS SQL 2012.

Результат тестирования:

В диаграмме эффективности я отобразил во сколько раз второй запрос выполняется быстрее от первого взависимости от объема выборки данных.

Я не эксперт, но для тех, кто хорошо разбирается в MS SQL привожу запросы сервера баз данных и их планы выполнения:

Первый запрос и план выполнения:

INSERT INTO #tt59 WITH(TABLOCK) (_Q_000_F_000, _Q_000_F_001)
SELECT
T1._Q_000_F_000, MIN(T2._Q_000_F_000)
FROM
#tt14 T1 WITH(NOLOCK)
INNER JOIN
#tt14 T2 WITH(NOLOCK)
ON (
T1._Q_000_F_000 < T2._Q_000_F_000)

GROUP BY T1._Q_000_F_000

Второй запрос и план выполнения:

INSERT INTO #tt59 WITH(TABLOCK) (_Q_000_F_000, _Q_000_F_001)
SELECT
DISTINCT
T1._Q_000_F_000, T2._Q_000_F_000
FROM #tt10 T1 WITH(NOLOCK)
INNER JOIN
#tt10 T2 WITH(NOLOCK)
ON ((
T1._Q_000_F_000 < T2._Q_000_F_000) AND T2._Q_000_F_000 IN
(SELECT
MIN(T3._Q_000_F_000) AS Q_001_F_000_
FROM #tt10 T3 WITH(NOLOCK)
WHERE (
T1._Q_000_F_000 < T3._Q_000_F_000)))

Собственно говоря, прирост производительности запроса без группировки очевиден.

Однако есть недостатки такого метода реализации. Если запустить обработку анализа запросов на файловой базе, то картина будет совсем противоположной.

Собственно говоря, все. 

В своей практике я использую именно второй метод связи таблиц для построения последовательности, это я и хотел отметить в двух разделах этой статьи.

Буду раз услышать ваши соображения по поводу построения запросов, конструктивную критику или предложения, но только  за исключением фраз "Статья баян" и прочее.

Спасибо.

Скачать файлы

Наименование Файл Версия Размер
Тест запросов

.epf 19,20Kb
08.12.15
3
.epf 19,20Kb 3 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. ivanov660 2343 07.12.15 10:53 Сейчас в теме
Использование в запросах виртуальной таблицы регистра накопления остатки и обороты зло.
4. DoctorRoza 07.12.15 12:26 Сейчас в теме
(1) ivanov660, это где Вы такое вычитали? А если статистика обновлена, индексы дефрагментированы все равно зло? Может так стоит говорить о РБ, хоть и с натяжкой?

Например в теме http://infostart.ru/public/306536/ пользователем ildarovich был предложен следующий вариант получения остатков товаров на каждый день:


Чувствую, но намечается нехилый батл! :)
5. nickpugachev 07.12.15 18:31 Сейчас в теме
(4) DoctorRoza,
это где Вы такое вычитали? А если статистика обновлена, индексы дефрагментированы все равно зло? Может так стоит говорить о РБ, хоть и с натяжкой?

стоит пару раз увидеть конечный запрос в sql

в зависимости от потребностей быстрее может быть выборка остатков на начало и изменений на каждый день. но нужно смотреть по ситуации.
8. DoctorRoza 08.12.15 09:19 Сейчас в теме
(5) nickpugachev, если Вы работаете с крупным производством, то, конечно же, разбирали основные типовые отчеты УПП 1.3. Например, ведомости (ВедомостьТоварыНаСкладах), то они все из виртуальных таблиц ОстаткиИОбороты. И это зло? "Сомневаюсь!" (Киселев). :) А если зло, то самое меньшее из! Хотя да, все по ситуации.
2. ya.Avoronov 109 07.12.15 12:10 Сейчас в теме
А я наивно верю и жду, что 1С даст возможность делать такие вот примитивные запросы:
Выбрать ДиапазонДат.Дата
	Из ДиапазонДат(&НачалоПериода, &КонецПериода, День) КАК ДиапазонДат


Выбрать ДиапазонЧисел.Число
	Из ДиапазонЧисел(&НачЧисло, &КонЧисло, &Шаг) КАК ДиапазонЧисел


Или я один такой?
Liris; savostin.alex; +2 Ответить
3. herfis 378 07.12.15 12:23 Сейчас в теме
(2) ya.Avoronov, Я не жду.
Так как "нормальных" и универсальных решений этой задачи не существует.
Либо сабжевый костыльно-антиреляционный подход (материалы статьи, кстати, довольно вторичны и боянисты), либо табличку засылать (что тоже далеко не фонтан).
Оптимально было бы табличку генерить на стороне сервера БД хранимкой. Это было бы как раз нормальное решение. Но 1С на это не пойдет, т.к. это повышает стоимость кроссплатформенной поддержки.
6. Yashazz 3582 07.12.15 19:07 Сейчас в теме
После Ильдаровича все такие публикации смотрятся как второсортный баян.
И насчёт виртуальной таблицы - согласен, зло почти всегда.
7. m..adm 205 07.12.15 20:07 Сейчас в теме
(6) Yashazz, Несколько вопросов. Ты кто такой? Ты построение запросов анализировал? Как относится к твоим бла-бла-бла о баянах?
16. Yashazz 3582 08.12.15 16:35 Сейчас в теме
(7) по пунктам:
Ты кто такой?
Посетитель сайта "Инфостарт".*
Ты построение запросов анализировал?
Как минимум маловнятный вопрос. Построение - это которое программист 1С в коде делает? Текстом, конкатенацией, или объектной моделью запроса? А может, это которое 1С делает, когда в язык запросов СУБД транслирует? Или это вообще о работе планировщика речь? Увы мне, не смог понять...
Как относится к твоим бла-бла-бла о баянах?
А вот Ильдарович уже и ссылку подкинул, и объяснил. Грешен я, занят был, некогда мне было своё частное мнение детально разжёвывать.

*а вообще спасибо, посмеялся
17. m..adm 205 08.12.15 17:06 Сейчас в теме
(16) Yashazz, Ильдарович свои соображения изложил внятно, мне не жалко будет на такой подход человека потратить время на ответ, чуть позже после работы. Ну а ты то тут каким боком? Сказал о зле виртуальных таблиц заезженную тему и на этом усё? Как автору статьи, потратившему все-таки хороший кусок времени на ее изложение, печально слышать какие-то темы о баянах. Посему, если нет времени, нет желания отписывать или есть прочие у тебя дискомфорты, тогда чуть полем-полем, а потом лесом и подальше от этой темы. В противном случае по существу, без выделывания. Ок? Надеюсь моя мысль услышана. Спасибо.
9. and_sk 14 08.12.15 10:01 Сейчас в теме
чето перемудрено вроде

ВЫБРАТЬ
НАЧАЛОПЕРИОДА(Товар.Период, ДЕНЬ) КАК Дата,
Товар.КоличествоКонечныйОстаток
ИЗ
РегистрНакопления.ТоварыОрганизаций.ОстаткиИОбороты(&Нач, &Кон, Регистратор, , ) КАК Товар
10. m..adm 205 08.12.15 10:23 Сейчас в теме
(9) and_sk, что именно перемудрено?
11. and_sk 14 08.12.15 10:31 Сейчас в теме
даты в отрыве от данных частные задачи
и мне кажется не требуют какогото особого подхода
решаются в порядке поступления))
12. m..adm 205 08.12.15 11:02 Сейчас в теме
(11) and_sk, да, в большинстве случаев так и есть. Но есть задачи как расчет среднесуточного остатка или оборачиваемости товара. В таких задачах надо все даты.
18. ildarovich 7147 08.12.15 17:14 Сейчас в теме
(12)
Но есть задачи как расчет среднесуточного остатка или оборачиваемости товара. В таких задачах надо все даты
На всякий случай замечу, что в статье Расчет средних по периодам в запросе - это элементарно! показано, как рассчитать среднедневной остаток вообще БЕЗ расчета остатков по дням.
21. m..adm 205 08.12.15 23:32 Сейчас в теме

(18) ildarovich,
На всякий случай замечу, что в статье Расчет средних по периодам в запросе - это элементарно! показано, как рассчитать среднедневной остаток вообще БЕЗ расчета остатков по дням.
. Математика Вашего расчета сходится и оптимальна. Тогда поправлю себя "Но есть задачи как расчет среднесуточного остатка или оборачиваемости товара, в которых надо все даты.
13. ildarovich 7147 08.12.15 12:10 Сейчас в теме
Не удержусь и покритикую. По задаче 3(остатки):

1) "Мой" запрос можно оптимизировать;
2) Направление оптимизации выбрано (по моему мнению) неверное;
3) Такое решение встречается часто, то есть новизны в предложенном решении нет.

Подробнее по пунктам:

1) Целью написания исходного запроса являлась компактность записи. Хотелось уложиться ровно в один запрос. Поскольку он появился в теме, где эта задача решалась 5-6 запросами в пакете. То есть оптимизация была отодвинута на второй план.
Для этого в качестве основной таблицы была взята таблица остатков и оборотов с разворотом по дням. Хотя на самом деле остатки реально используются (входят в сумму) только в первом дне периода. А в остальные дни используются только обороты. На этом можно сэкономить.

Для этого нужно взять таблицу остатков и оборотов не по дням, а в целом за период. Использовать только начальные остатки из этой таблицы. При этом можно ожидать, что отсутствующие в начале периода товары будут не отсутствовать вообще (если взять только остатки), а выводится нулями, если запросить (но не использовать) количество прихода и расхода. Поскольку период отчета обычно кратен периоду хранения итогов, можно ожидать, что эта таблица просто возьмется из рассчитанных итогов.
Кроме того, нужно будет взять таблицу оборотов по дням. Хотя кажется, что можно взять и движения, это будет неправильно. Предварительная группировка движений по дням сократит время на сравнение на попадание в диапазон дней.
Таблицы можно СОЕДИНИТЬ и получить тот же один запрос, но с двумя соединениями. Но НАДЕЖНЕЕ таблицы ОБЪЕДИНИТЬ перед соединением с датами.
В итоге получается такой запрос (на примере регистра Товары на складах):
ВЫБРАТЬ 0 КАК Х
ПОМЕСТИТЬ Разряд
ОБЪЕДИНИТЬ ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВЫБРАТЬ 9
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, (Р0.Х * 10 + Р1.Х) * 10 + Р2.Х) КАК Период
ПОМЕСТИТЬ ВТДаты
ИЗ
	Разряд КАК Р0,
	Разряд КАК Р1,
	Разряд КАК Р2
ГДЕ
	ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, (Р0.Х * 10 + Р1.Х) * 10 + Р2.Х) <= &КонецПериода
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	&НачалоПериода КАК Период,
	Остатки.Номенклатура,
	Остатки.КоличествоНачальныйОстаток + 0 * Остатки.КоличествоПриход + 0 * Остатки.КоличествоРасход КАК Остаток
ПОМЕСТИТЬ ВТДвижения
ИЗ
	РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Период, , Склад = &Склад) КАК Остатки

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	Обороты.Период,
	Обороты.Номенклатура,
	Обороты.КоличествоОборот
ИЗ
	РегистрНакопления.ТоварыНаСкладах.Обороты(&НачалоПериода, &КонецПериода, ДЕНЬ, Склад = &Склад) КАК Обороты
;

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

СГРУППИРОВАТЬ ПО
	Движения.Номенклатура,
	Даты.Период
Показать
В этом запросе нет лишних действий, именно его и нужно тестировать для сравнения. Он сохраняет суть исходного "моего" запроса: для нахождения промежуточных остатков накапливаются обороты. Именно так и работает нахождение остатков платформой, если остатки требуется рассчитать внутри периода итогов.

2) Почему кажется, что подход из статьи содержит лишние действия? - Сначала считаются остатки внутри периода итогов. Потом остатки интерполируются как срез последних на каждую дату. То есть для каждой находится дата последнего изменения. И соединением остаток берется из нее. Индекс (на построение которого тоже идет время) здесь помогает мало (в срезе последних регистра сведений он берется готовый). Кажется, что действия сложнее и их больше. Не на много, но больше. Плюс соединения, а не простая группировка.

3) Вот одна из ссылок: http://infostart.ru/public/101321/ . Можно еще много найти, если постараться.
Liris; myjob1c; Vlasenko.Oleg; Makushimo; kuzyara; Yashazz; artbear; +7 Ответить
14. ildarovich 7147 08.12.15 13:12 Сейчас в теме
+(13) По задаче 4:
Всего два свойства? - Но тогда все должно быть ГОРАЗДО проще!
Все комбинации получается сразу всего одним простым запросом:
ВЫБРАТЬ
	Инь.Товар,
	Инь.Значение КАК ЗначениеСвойства1,
	Янь.Значение КАК ЗначениеСвойства2
ПОМЕСТИТЬ Ответ
ИЗ
	ВТ КАК Инь
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ КАК Янь
		ПО Инь.Товар = Янь.Товар
			И Инь.Свойство < Янь.Свойство
Показать

Если варианты нужно пронумеровать, то
ВЫБРАТЬ
	Ответ.Товар КАК Товар,
	КОЛИЧЕСТВО(Слева.Товар) КАК НомерВарианта,
	Ответ.ЗначениеСвойства1,
	Ответ.ЗначениеСвойства2
ПОМЕСТИТЬ ОтветСНомеромВарианта
ИЗ
	Ответ КАК Слева
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Ответ КАК Ответ
		ПО Слева.Товар = Ответ.Товар
			И (Слева.ЗначениеСвойства1 < Ответ.ЗначениеСвойства1
				ИЛИ Слева.ЗначениеСвойства1 = Ответ.ЗначениеСвойства1
					И Слева.ЗначениеСвойства2 <= Ответ.ЗначениеСвойства2)

СГРУППИРОВАТЬ ПО
	Ответ.Товар,
	Ответ.ЗначениеСвойства1,
	Ответ.ЗначениеСвойства2
Показать
Если нужен ответ "в столбик", то
ВЫБРАТЬ
	Ответ.Товар,
	Ответ.НомерВарианта,
	Ответ.ЗначениеСвойства1
ИЗ
	ОтветСНомеромВарианта КАК Ответ

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	Ответ.Товар,
	Ответ.НомерВарианта,
	Ответ.ЗначениеСвойства2
ИЗ
	ОтветСНомеромВарианта КАК Ответ
Показать
Названия свойств также добавить ничего не стоит. Конечно, нумерация вариантов тут помедленнее, но это также легко ускорить, не прибегая к запутанному запросу из статьи. По сути взят универсальный метод из статьи "Запрос-комбинатор" как некая формула, выполнена подстановка (число свойств = 2), а упрощения (раскрытия скобок, приведение и прочее не сделаны). Вот и получился запрос-крякозябра.
А вообще исходная задача была и интересная и практическая. Без универсальности там было не обойтись.
22. m..adm 205 09.12.15 00:06 Сейчас в теме
(14) ildarovich,
По задаче 4:
Всего два свойства? - Но тогда все должно быть ГОРАЗДО проще!
Да, можно и проще. Первоначально делал запрос на разные количества свойств, а потом за отустствием времени плюнул, "обрубил" его и выложил как есть.
35. m..adm 205 12.12.15 12:44 Сейчас в теме
(14) ildarovich,
По задаче 4:
Всего два свойства? - Но тогда все должно быть ГОРАЗДО проще!
Все комбинации получается сразу всего одним простым запросом

Запрос по задаче 4 у меня был сложным и в несколько пакетов, т.к. разрабатывался как универсальный запрос на произвольное количество свойств и в последствии был "обрублен" и выложен как есть. Исправил этот недоработанный момент и изменил 4-й раздел статьи. В разделе я выложил новый запрос, который без дополнительных временных таблиц выдаст выборку "в столбик" отсортированных и пронумерованных комбинаций сочетаний свойств товара. Как Вам это? ГОРАЗДО проще или нет?
37. ildarovich 7147 12.12.15 15:02 Сейчас в теме
(35) запрос по разделу 4 я посмотрел. Про "зеркально" понял. Предыдущего варианта у меня нет, поэтому насколько удалось упрощение сказать не могу. Мог бы подумать, как упростить нумерацию в вашей схеме, но большого желания нет. Написав ту исходную статью, не увидел большого интереса к этой задаче. Хотя она взята из практики. Те, кто въехал, делают то же самое через декартово соединение таблиц свойств. Нумерацию чаще удобнее делать вне запроса. Поэтому задача довольно экзотическая и тратить на нее время жалко.
Но у меня встречный вопрос: а зачем вам свое решение в этой задаче. Ведь в исходной статье решение исчерпывающее и универсальное (на ЛЮБОЕ количество свойств). С быстродействием проблем нет. Свойства два - тогда хватит одного повтора и длина запроса будет меньше или равна длине вашего варианта (вы немного схитрили и записали в одну строку несколько полей). Если раскрыть запросы конструктором, то длина будет почти одинаковой. А в комментарии я показал ну очень простую и понятную схему для двух свойств без всякого накопления. Зачем вам топтаться на этой экзотической и уже решенной задаче? Какую новизну, какую идею вы хотели привнести в решение?
(32) смоделированная вами ситуация выглядит надуманной. В варианте (13) выпадают только строки, которые имеют нулевые начальные И конечные остатки И приход в середине интервала И который весь закрывается возвратом (приходом с минусом). Редкая ситуация. Можно было бы пренебречь. Ведь мы пренебрегаем случаями, когда приход и расход делается в один день (гардероб, детский сад). Но в принципе я не возражаю доработать запрос на отмеченный в (32) случай. Сделаю это чуть позже. Заранее могу сказать, что результаты теста будут зависеть от данных базы. Поэтому для честного соревнования нужно будет договорится о том, на каких данных будет идти тестирование. Кроме того, я знаю еще минимум три-четыре других способа интерполяции остатков. Их пока не рассматриваем?
38. m..adm 205 12.12.15 22:54 Сейчас в теме
(37) ildarovich, По 4 разделу.
Но у меня встречный вопрос: а зачем вам свое решение в этой задаче. Ведь в исходной статье решение исчерпывающее и универсальное (на ЛЮБОЕ количество свойств)
Первоначально я хотел сделать универсальный пакетный запрос на любое количество видов свойств, в котором не требовалось бы делать умножение таблиц взависимости от количества видов свойств. На этой реализации я заштопорился и чтобы не тратить уйму времени, выложил частичную реализацию - запрос на 2 вида свойств, с любым количеством значений свойств. Предыдущий запрос был интересен тем, что надо было немного поднапрячь воображение для разбора его алгоритма работы. Ваше заявление "можно ГОРАЗДО проще"я принял как вызов и вот Вы видите запрос БЕЗ временных таблиц, который делает комбинации любого набора значений свойств в разрезе товара но с ограничением: в пределах одного товара должно быть только 2 вида свойств. Запрос написан компактнее для удобства понимания. Если реализовать идентичный механизм на базе Ваших запросов в статье http://infostart.ru/public/295343/ то он будет не такой компактный. Я донес Вам свою мысль?

(32) смоделированная вами ситуация выглядит надуманной. В варианте (13) выпадают только строки, которые имеют нулевые начальные И конечные остатки И приход в середине интервала И который весь закрывается возвратом (приходом с минусом). Редкая ситуация. Можно было бы пренебречь. Ведь мы пренебрегаем случаями, когда приход и расход делается в один день (гардероб, детский сад). Но в принципе я не возражаю доработать запрос на отмеченный в (32) случай. Сделаю это чуть позже
Да, сделайте, я сравню потом производительность запросов. "Пренебречь" исключительными ситуациями и рядом данных во многих расчетах можно. Когда же речь идет о создании четкого алгоритма, то никто ничем не пренебрегает! В этом я категорически не соглашусь. В моей реализации запроса, день, который закрывается с нулевым оборотом будет отмечен с нулевым остатком и не выпадет из выборки как у Вас.

В заключение хочу подвести некий итог.
Я потратил достаточно времени на статью, чтобы поделиться одним из интересных моментов реализации выборки данных при получении остатков и срезов.
Я не утверждаю, что это единственный и тем-более правильный для каждого случая вариант реализации. Из моего опыта, на громадных объема данных, множеством временных таблиц и запросах в тысячи строк такой подход хорошо экономит время тем самым, увеличивают быстродействие системы.
Рациональное зерно в статье есть, однако что я вижу. Я открываю свою статью и вижу "Лучший комментарий" от Вас, в котором человек с огромной репутацией на этом ресурсе и опытом, косвенно говорит, что статья ни-о-чем. Этот комментарий сразу же поддерживает не глядя несколько человек. В итоге, читатель смотрит мельком статью, смотрит лучший комментарий, понимает "статья ни-о-чем" и уходит. Такой исход меня крайне не устраивает.
Посему, предлагаю как-то исправить эту неудобную ситуацию.

Далее Ваше внимание переключу на тему http://infostart.ru/public/421101/. В ней Вы тоже поспешили прокомментировать мою реализацию и выбились в "лучшие комментарии". В ней я выложил готовое решение под конкурс http://forum.infostart.ru/forum1/topic78895/ и получил за это вознаграждение. В конкурсе не шла речь о минимализме. Я сомневаюсь и готов поспорить, о компактности реализации задачи "Найти кратчайший путь коня между двумя заданными полями в теме http://infostart.ru/public/306536/. Посему, продолжу при наличии времени там.

Спасибо.

artichoke; +1 Ответить
39. herfis 378 14.12.15 12:06 Сейчас в теме
(38) Статьи ildarovich'а предельно лаконичны, поучительны и содержательны. За что ему большой респект. Непросто писать просто о сложном.
В вашей статье, по сути, первичен и интересен только один момент (лично для меня, конечно же) - способ оптимизации производительности запросов 1С в MSSQL в некоторых шаблонных ситуациях, путем использования коррелирующего подзапроса. Но это эта информация подана значительно более громоздко, чем могла бы. Отдельная статья с таким исследованием (а если бы еще и в сравнении с другими СУБД - вообще бомба) смотрелась бы гораздо более интересно и была бы более эффективна для аудитории, по моему мнению. Намеки на заангажированность ildarovich'а, которая якобы встает стеной между вами и аудиторией, мешая ей адекватно потреблять инновационный контент - несостоятельны и вызывают улыбку.
Но мне понятно ваше негодование как автора и творца, который потратил время и силы, а в ответ получил неблагодарную публику. Да как они смеют, вообще!
ildarovich; +1 Ответить
40. m..adm 205 14.12.15 14:50 Сейчас в теме
(39) herfis,
Статьи ildarovich'а предельно лаконичны, поучительны и содержательны

Да, согласен с Вами. Товарищ ildarovich молодец.
..подана значительно более громоздко, чем могла бы
тоже согласен, потому что привык все разжевывать. Тем более, я применил подход этот в нескольких запросах.
Публика-то разная. Кому-то надо разжевывать, а кто-то и на пальцах поймет.
Да как они смеют, вообще!
- 100%, Вы мои мысли прочли! :) Прямо и добавить нечего.
Но добавлю. Во всем надо сомневаться и учиться мыслить самому, а не только "как в книжке написано или кем-то сказано".
Спасибо за веселый комментарий.

15. ildarovich 7147 08.12.15 13:22 Сейчас в теме
+(13) "изюминки" во второй половине задачи 3 я не увидел. Если речь идет о замене соединения на запрос с конструкцией ГДЕ (Поле1, Поле2) В (Выбрать Поле1, Поле2 Из ...), то эффективность такой замены нужно тестировать на разных СУБД. Смотреть планы запроса. Повторы при замерах тоже настораживают. Результат (Выбрать Поле1, Поле2 Из ...) и индекс для поиска, возможно, в кэше оставался, что и давало прирост. Также непонятны причины появления двух разных цен одного типа на одну дату, которые по регистратору нужно разделять (МАКСИМУМ?ссылка). Кажется, такой вариант вообще должен быть еще при записи исключен.
20. m..adm 205 08.12.15 23:14 Сейчас в теме
(15) ildarovich, "изюминки" во второй половине задачи 3 я не увидел. - задача 5 на том-же запросе. Добавил в статью. Для меня такой подход, ну не сколько изюминка, возможно кислинка, но приятная :)
19. m..adm 205 08.12.15 23:12 Сейчас в теме
(13) ildarovich, 1) Ваш запрос был взят для сравнительного примера. В разделе 3 статьи я получил небольшой процент прироста производительности своего запроса в сравнении с Вашим. Эти тесты я выполнил вручную в консоли запросов. На досуге найду время и проведу тесты с использованием обработки, которую я описал в разделе 5. Отпишу о результатах.
Относительно запроса, который Вы приводите как более оптимальный в этих комментариях. Меня терзают сомнения, что он более оптимален, т.к. в нем присутствует выборка из двух виртуальных таблиц регистра. И в случае, когда, дисковая система сервера баз данных оставляет желать лучшего, чтение двух наборов данных может дать дополнительную задержку. Думаю, выборки из одной жирной таблицы остатки-обороты тут достаточно, но этот момент также требует тестирования.
"Но НАДЕЖНЕЕ таблицы ОБЪЕДИНИТЬ перед соединением с датами" - тут немного смешно звучит, ведь "НАДЕЖНО" оно и в Африке надежно будь то запрос-объединение или соединение полной таблицы с выборочными данными.
"Направление оптимизации выбрано (по моему мнению) неверное" - Ваше мнение, спасибо. Я же в статье показываю что при реализации запроса с паралельным фильтрующим соединением в клиент-серверном варианте получаем значительный прирост быстродействия по сравнению с запросом с группировкой. Ключевым в этой реализации есть индексированная базовая таблица. На ее формирование уйдет время и ресурсы сервера, однако, затраты времени на формирование таблицы будут перекрыты выгодой от производительности запроса. Ресурсами сервера пренебрегаем, т.к. я рассматриваю эту тему, как вариант убыстрения выполнения запроса на больших объемах данных, а не минимизацию кода или потребления ресурсов. У Вас есть похожая статья, было бы интересно, сравнить результаты от выходы решений. Правда, мои тесты производились на числовых данных, на индексированных данных типа "дата", боюсь, будут другие результаты.
"Такое решение встречается часто, то есть новизны в предложенном решении нет." - поделитесь ссылочкой, а то я это решение из своей практики взял, а не с Googля.
Спасибо
25. ildarovich 7147 09.12.15 08:07 Сейчас в теме
(19) по вопросам 1-4 взаимопонимания мы не достигли, ну да ладно, я свое мнение высказал.
По вопросу 5 очень интересно. Такая информация (об эффективности в MS SQL ПО (...) В (ВЫБРАТЬ ... ИЗ)) здесь проскакивала, но без замеров и демонстрации плана запроса она не была так убедительна. Время на построение индекса в замерах учитывалось? - Проверю, буду иметь ввиду. Жаль только, что эффективность этого приема так сильно зависит от СУБД.
26. m..adm 205 09.12.15 09:10 Сейчас в теме
(25) ildarovich, нет. время, потраченное на создание индексов в тесте не учитывалось. Предполагалось, что на входе у нас уже есть индексированные таблицы .
30. m..adm 205 10.12.15 23:34 Сейчас в теме
(13) ildarovich,
В этом запросе нет лишних действий, именно его и нужно тестировать для сравнения. Он сохраняет суть исходного "моего" запроса: для нахождения промежуточных остатков накапливаются обороты. Именно так и работает нахождение остатков платформой, если остатки требуется рассчитать внутри периода итогов.

Я не интересовался, как работает механизм нахождения остатков платформой. Если есть ссылка на описание, поделитесь.
Я планировал сделать сравнительные замеры своего запроса и запроса, который был предложен Вами выше в комментариях, да пока это невозможно, т.к. запросы выдают разные наборы данных. Предоставьте пожалуйста самый оптимальный с Вашей точки зрения запрос, который за любой период с отбором по складу даст выборку остатков номенклатуры на каждый день из периода. Я продолжу потом сравнительный анализ. В Вашей реализации запроса по некоторой номенклатуре не будет данных по остаткам на каждый день. Это вызвано тем, что для реализации алгоритма расчета Вы использовали периодичность "Период" таблицы "ОстаткиИОбороты". При такой реализации, если товар пришел первый раз на склад позже "НачалоПериода" - по этому товару будут отсутствовать данные по остаткам по дням от "НачалоПериода" до даты поступления этого товара.
31. ildarovich 7147 11.12.15 10:54 Сейчас в теме
(30) (30) информация как считаются остатки платформой внутри периода итогов есть в "белой книге". Это двухтомник "Профессиональная разработка в системе 1С:Предприятие".
Я специально проверил насчет
В Вашей реализации запроса по некоторой номенклатуре не будет данных по остаткам на каждый день. Это вызвано тем, что для реализации алгоритма расчета Вы использовали периодичность "Период" таблицы "ОстаткиИОбороты". При такой реализации, если товар пришел первый раз на склад позже "НачалоПериода" - по этому товару будут отсутствовать данные по остаткам по дням от "НачалоПериода" до даты поступления этого товара.
и ЧТОБЫ ЭТОГО НЕ БЫЛО использовал конструкцию
ВЫБРАТЬ
    &НачалоПериода КАК Период,
    Остатки.Номенклатура,
    Остатки.КоличествоНачальныйОстаток + 0 * Остатки.КоличествоПриход + 0 * Остатки.КоличествоРасход КАК Остаток
ПОМЕСТИТЬ ВТДвижения
ИЗ
    РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Период, , Склад = &Склад) КАК Остатки
где используется
+ 0 * Остатки.КоличествоПриход + 0 * Остатки.КоличествоРасход
которая должна давать нулевые записи, даже, если остатков на начало не было. А вы проверяли или заключение умозрительное?
32. m..adm 205 11.12.15 12:08 Сейчас в теме
(31) ildarovich,
которая должна давать нулевые записи, даже, если остатков на начало не было. А вы проверяли или заключение умозрительное?

Я действую по принципу "доверяй, но проверяй".Смотрите две ситуации с таблицей "Остатки и обороты" для такого стечения данных по движениям товара в отношении к нашему периоду выборки. В одном случае на конец периода есть остаток и таблица остатков-оборотов по периодичности "Период" дает данные. В другом случае - на конец периода нет остатка, таблица не дает данные при использовании периодичности "Период". Для второго случая результирующего запроса выпадают данные, до первого поступления товара. Первая дата в такой выборке будет - дата первого оборота из таблицы оборотов. Если бы использовалась периодичность остатков и оборотов "День", тогда мы получили бы данные, да логика Вашего общего запроса тогда не работала б. Поэтому я и написал, дайте окончательный правильный запрос.
Прикрепленные файлы:
ildarovich; +1 Ответить
23. logarifm 1084 09.12.15 01:06 Сейчас в теме
У вас на СКЛ сработал паралелизм, необходимо отключать паралелиться запросы.
24. m..adm 205 09.12.15 02:09 Сейчас в теме
(23) logarifm, Да, это план выполнения запроса с поиском минимального значения при группировке. Этот процесс СКЛ разбил на несколько потоков. Почему необходимо отключать? Хоть это больше потребляет ресурсов в единицу времени, зато убыстряет выполнение задачи.
27. alest 09.12.15 12:45 Сейчас в теме
Поэтому я рекомендовал бы не делать сложных выборок-соединений с группировкой из виртуальных таблиц, а прочитать необходимые данные из виртуальной таблицы регистра во временную и далее их обрабатывать последующими пакетами запроса.

Смотрю результат оптимизации - то же соединение, группировка да еще и помещение во временную таблицу. Прирост скорости, скорее всего, получен был за счет замены таблицы Курсов на порождающий запрос. А в запросе так и осталось соединение Дней с виртуальной таблицей остаков/оборотов.
Прошу прощения, поспешил.
28. kosmo0 99 10.12.15 09:02 Сейчас в теме
Порой смотрю на тексты запросов и возникает мысль - страшно далеки они от народа практической реализации.

Почему
ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000 КАК Число
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3
Показать


а не
ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ВТ1.Ч + ВТ2.Ч*10 + ВТ3.Ч*100 + ВТ0.Ч*1000 КАК Число //изменен порядок ВТ0,ВТ1,ВТ2 и ВТ3
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3
Показать


Или потом сортировать результат теряя время полученное от всех предыдущих оптимизаций?
29. m..adm 205 10.12.15 10:42 Сейчас в теме
(28) kosmo0,
Порой смотрю на тексты запросов и возникает мысль - страшно далеки они от народа практической реализации.

1.В практической реализации сортировка необходима не только по датам, но и по другим разрезам выборки, поэтому все-равно придется сортировать или запросом, или на этапе компоновки результата. В практической реализации пакетных запросов с большим объемом данных важна индексация в первую очередь и правильное соединение запросов.
2. Изменив порядок таблиц в выражении, Вы можете однозначно утверждать, что в таком случае выборка будет всегда отсортирована? Результат получился таковым, потому что SQL сформировал такой план выполнения запроса. У Вас есть доводы?
3. Применение таких выборок - страховка от возможных потерь данных, в сравнении со случаями, когда периоды мы получаем из регистров. Что Вы там говорили о практике?
33. kosmo0 99 11.12.15 15:20 Сейчас в теме
(29) Прежде всего хотелось бы адекватной реакции по сути, а не ответа в стиле -"мне адреналин с мочой в голову ударил и я стал контратаковать". (это видно по пункту 3 который добавлен до кучи и совершенно не относится к моему посту).

По пункту 1. В большинстве случаев желание получить список чисел или дат подряд означает что важно получение данных в разрезе дат. (но, опять же, это в реальной жизни).
По пункту 2. Вы можете ОДНОЗНАЧНО УТВЕРЖДАТЬ что верна Ваша точка зрения?

Я могу утверждать что описанный подзапрос был банально скопирован. Оптимизация запросов это желание привести к некому идеальному результату. Люди стремящиеся к идеалу не любят беспорядка. Результат же скопированного подзапроса это маленький бардак.

На этом откланяюсь, участвовать в говносраче не имею желания.
34. m..adm 205 11.12.15 15:39 Сейчас в теме
(33) kosmo0, 1. Вы залетели в эту тему с мыслью и заявлением
Порой смотрю на тексты запросов и возникает мысль - страшно далеки они от народа практической реализации.
. Я опровергну эту мысль тем, что подчеркнул: перестроенная Вашим образом выборка дала результат отсортированных чисел по возрастанию лишь потому, что сервер баз данных сформировал такой план выполнения запроса. Попросту говоря, вы подобрали запрос таким образом, чтобы результат бы отсортирован. Однако повторю то, что я хотел сказать. Ваша структура запроса не дает гарантии, что на другой версии сервера баз данных будет такой-же план выполнения запроса и Вы получите отсортированную таблицу. Логично?
2. Я также не могу утверждать, что на другой версии сервера базы данных, не получится упорядоченная таблица, т.к. это требует анализа, хорошего знания работы платформы сервера.
3. Мои выводы основаны на том, что в таком запросе 1С с сочетанием таблиц не прослеживается явное создание сортировки. Если бы Вы построили эту выборку на базе "Левых" соединений, возможно я бы согласился.
4. И последнее. Не я заявлял "далеко от практики" без особых аргументов. Я говорю и анализирую. В случае моей ошибки, я поправляю себя. Вы можете заметить перечеркнутые выражениях в моих постах. Посему, г...срач, как Вы говорите, скорее всего развожу не я.
Спасибо за Ваше участие.
36. m..adm 205 12.12.15 13:07 Сейчас в теме
Обработку для тестирования запросов по 5-му разделу статьи прилагаю тут, т.к. она идет как приложение к статье, а не программный продукт. При запуске не стоит сразу указывать много временных таблиц для анализа и большие размеры таблиц, т.к. выполнение может быть продолжительным, особенно, на файловом варианте. Ссылка на обработку: http://www.ex.ua/691114295869
Оставьте свое сообщение

См. также

Вам нравятся запросы в 1С? Промо

Практика программирования Разработка v8 v8::Запросы 1cv8.cf Абонемент ($m)

Речь не только о том, что простейший запрос с "легальным" оформлением растянется на пол-экрана, речь еще обо всем, что нужно написать "в нагрузку" к тексту запроса. Все эти "Новый Запрос", "УстановитьПараметр" и последующие пляски с обработкой результата... Пора с этим заканчивать!

1 стартмани

03.07.2019    21174    5    m-rv    88    

Интерактивная справка по объектам 1С (автономное расширение)

Практика программирования Работа с интерфейсом v8 ERP2 Абонемент ($m)

База знаний, подключаемая к объектам основной базы. Ведётся интерактивно, формируется в виде статей прямо в 1С (текст, картинки, таблицы, ссылки). Есть возможность прикрепления файлов, привязки к объектам 1С, возможности рейтинга и комментирования пользователями.

3 стартмани

29.09.2020    6601    33    sapervodichka    33    

Конвейер проверки качества кода

Инструментарий разработчика Практика программирования Математика и алгоритмы v8 1cv8.cf Абонемент ($m)

Jenkinsfile для выполнения проверки качества кода. Собирает информацию с АПК, EDT и BSL-LS. Сопоставляет ошибки с гит-репозиторием, выгруженным ГитКонвертором. Отправляет в Сонар.

3 стартмани

04.09.2019    25541    22    Stepa86    46    

Алгоритмы поиска пути в графе

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

Реализуем алгоритмы поиска пути в графе на платформе 1С 8.3, такие как алгоритм А*, поиск в ширину, жадный поиск, алгоритм Дейкстры и вконце волновой.

1 стартмани

09.07.2019    17949    12    RonX01    10    

ВСТАВИТЬ В Справочник.Номенклатура (Код, Наименование) ЗНАЧЕНИЯ ("001", "Новый товар") Промо

Практика программирования v8 v8::Запросы 1cv8.cf Абонемент ($m)

Вас не обманывают ваши глаза, это запрос на изменение данных! И это работает без прямого доступа к БД, регистрации и смс.

1 стартмани

01.06.2018    30878    86    m-rv    57    

Работа с публикациями "Инфостарт"

Практика программирования О сообществе WEB v8 УУ Абонемент ($m)

Работа с рублевыми публикациями на сайте "Инфостарт": ведение клиентов, заказов, обновление файлов публикации, рассылка обновлений.

1 стартмани

13.09.2018    22120    13    RocKeR_13    16    

HTTP Сервисы: Путь к своему сервису. Часть 3

Инструментарий разработчика Практика программирования v8 1cv8.cf Абонемент ($m)

Продолжение статьи «HTTP Сервисы: Путь к своему сервису. Часть 2». В предыдущих частях мы использовали только Get, в этой части поговорим о других методах и длительных операциях.

1 стартмани

27.08.2018    38713    56    dsdred    17    

Позиционирование в помещении с помощью нейросети по сигналу Wi-Fi. Интерактивная карта склада в 1С с показом позиции

Инструментарий разработчика Практика программирования v8 Абонемент ($m)

Данная публикация содержит в себе редактор и интерактивную карту склада или иного помещения, на которой в реальном времени отображается позиция устройства, координаты которого вычисляются по уровням сигнала нескольких роутеров Wi-Fi. В статье и приложенным к ней разработкам предлагаются инструменты и методика для реализации вычисления точной геопозиции внутри помещений с помощью нейронной сети. Конфигурация написана на релизе 1С:Предприятие 8.3.12.1412, клиентское приложение имеет минимальный уровень совместимости SDK -16.

5 стартмани

09.08.2018    28632    26    informa1555    26    

Заполняем по шаблону (по умолчанию) Промо

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

Простой в подключении, универсальный и достаточно удобный механизм заполнения реквизитов произвольных документов/справочников значениями по умолчанию. Реализован в расширении, но может быть и непосредственно включен практически в любую конфигурацию на управляемых формах простым копированием одной формы и двух команд. Весь код в статье.

1 стартмани

08.02.2018    28701    19    mvxyz    17    

Работа с данными выбора

Практика программирования Работа с интерфейсом v8 Россия Абонемент ($m)

В управляемом интерфейсе заложена мощная возможность описывать связи реквизитов формы через параметры. Установка параметров связей позволяет ограничить выбор данных так, чтобы целостность данных была обеспечена на этапе ввода. Однако без дополнительного программирования задать можно только самые простые связи. Такие условия связи, как зависимость от реквизита через точку или зависимость через дополнительное отношение, заданное в регистре сведений - уже задать без программирования не получится.

1 стартмани

17.07.2018    49032    17    kalyaka    16    

Полезные примеры составления схемы компоновки данных #2

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

Еще один набор примеров как решить частные задачи в СКД

1 стартмани

22.05.2018    31687    11    SITR-utyos    13    

Печатная форма, сделанная как расширение конфигурации для БП 3.0. Новые возможности БСП

Практика программирования Универсальные печатные формы v8 БП3.0 Абонемент ($m)

Печатные формы на внешних обработках скоро канут в лету. На смену им приходят ПФ, реализованные в виде расширений конфигурации. Не нашел на сайте примеров таких расширений. Привожу пример подобного расширения для БП 3.0.

1 стартмани

06.12.2017    27416    54    kwazi    6    

Нечеткий поиск одним запросом Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Использование механизма полнотекстового поиска в 1С не всегда оправдано, т.к. построение индекса и поддержание его в актуальном состоянии может значительно нагружать систему. Предлагаемая реализация нечеткого поиска методом N-грамм выполняется одним запросом, что позволяет производить поиск в любой таблице и не требует предварительного построения индекса.

1 стартмани

28.12.2015    28225    71    vasvl123    9    

Паузы при исполнении кода (Sleep для 1С)

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

Решил проверить все найденные варианты паузы для 1С. В результате получилась обработка для тестирования и небольшая статья с итогом.

1 стартмани

28.11.2017    47047    12    swimdog    42    

Макет в СКД - пример всех возможных типовых вариантов

Практика программирования Инструментарий разработчика v8 v8::СКД 1cv8.cf Абонемент ($m)

Макет СКД: наглядное представление того, что, как и куда выводится при типовых настройках.

1 стартмани

09.11.2017    22257    76    freelancer    4    

Telegram-боты

Практика программирования v8 Абонемент ($m)

Описание теории, разбор архитектуры и пример реализации telegram-ботов. Сразу скажу, со структурированием изложения мало что могу поделать. :) редакция от 18.07.2018 Правки последней редакции выделены жирным.

1 стартмани

01.09.2017    33238    132    PLAstic    59    

1С: Предприятие + корпоративный чат, как наладить оперативные уведомления за 10 минут Промо

Практика программирования v8 Абонемент ($m)

Как сделать автоматические уведомления о разных событиях из 1С в корпоративный чат MyChat для сотрудников компании

1 стартмани

14.08.2016    48578    36    Demanoidos    60    

Умный дом на 1С + ардуино

Практика программирования v8 Абонемент ($m)

Конфигурация для автоматизации быта программиста 1C и не только. В данной статье будет рассказано, как можно использовать 1С для задач, не входящих в стандартные рамки этой платформы. Например, управление домом. В качестве периферии для подключения будет использован микроконтроллер (МК) Ардуино, но на нём не будет никакой логической нагрузки, весь процесс будет проходить на сервере 1С. Работа с пинами ввода/вывода происходит напрямую из 1С.

1 стартмани

07.08.2017    23165    21    sasha777666    63    

Расширения конфигураций 1С: учимся перехватывать методы

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

В этой статье я на примерах разберу некоторые механизмы расширений конфигураций 1С. А именно «перехваты» методов модуля объекта и «перехваты» событий формы и элементов формы. Данная статья написана с учебными целями, чтобы показать, как при помощи расширений конфигурации можно делать такие доработки, ради которых раньше приходилось снимать конфигурацию с поддержки.

1 стартмани

30.05.2017    132516    13    signum2009    48    

Регулярные выражения – это просто. Построитель и отладчик регулярных выражений

Инструментарий разработчика Практика программирования v8 1cv8.cf Абонемент ($m)

Предлагается к использованию построитель регулярных выражений. Выполненный в виде внешней обработки, он позволит строить сложно-структурированные выражения на основе параметрического описания, тестировать их, и в результате получить программный код 1С.

1 стартмани

13.03.2017    31925    113    romasna    49    

Быстрое определение интервалов в запросе Промо

Практика программирования v8 Абонемент ($m)

В статье описывается новый метод определения интервалов между данными различных записей в запросе. В отличие от общеизвестного метода, время работы предлагаемого метода зависит от объема данных ЛИНЕЙНО. Это обеспечивает ему значительный выигрыш по быстродействию на больших объемах данных. В качестве иллюстрации возможностей метода приведен отчет, показывающий гистограмму распределения времени между продажами.

1 стартмани

01.10.2015    52159    35    ildarovich    41    

Распознавание текста с помощью нейросетей Google Cloud Vision и 1С

Практика программирования v8 1cv8.cf Абонемент ($m)

Возможности Google Cloud Vision в распознавании текста.

1 стартмани

08.02.2017    30072    127    kiv1c    18    

Графическая схема. Управление при помощи XDTO.

Практика программирования v8 Абонемент ($m)

В статье описывается методика программного управления элементами графической схемы при помощи механизма XDTO. Приложена готовая к использованию библиотека функций для создания и удаления графических объектов, а также для связи элементов схемы соединительными линиями.

2 стартмани

16.01.2017    22782    105    Alxby    23    

Простой редактор плана помещения JavaScript

Практика программирования Работа с интерфейсом v8 1cv8.cf Абонемент ($m)

На ресурсе сейчас очень много решений, которые позволяют редактировать карты, используя географические схемы. Так же много решений, которые позволяют редактировать объекты онлайн веб-карт. Мне же нужно было простое решение, для того чтобы расставить квадратные объекты на плане, показать их пользователю. Ну и распечатать, опять же. Я решил написать простенький редактор на JavaScript с использованием библиотеки Raphael.

1 стартмани

23.11.2016    21459    96    igel9780    22    

Хранение файлов в томах на диске (для УПП 1.3) Промо

Практика программирования v8 УПП1 Абонемент ($m)

Доработка типовой УПП 1.3 в плане хранения присоединенных файлов вне базы данных

2 стартмани

05.06.2016    58212    10    wowik    32    

Работа с двоичными данными на примере чтения файлов изображений. Новые возможности 8.3.9

Практика программирования WEB v8 1cv8.cf Россия Абонемент ($m)

В статье приводятся новые функции по работе с двоичными данными, появившимися в версии платформы 8.3.9 , на примере анализа формата и размера изображений. А также пример отправки изображения через API ВКонтакте с помощью новых объектов (без использования ОбъединитьФайлы())

1 стартмани

14.11.2016    26593    16    Anton64    22    

Загрузка файлов на сервер с прогрессом и докачкой

Практика программирования v8 1cv8.cf Россия Абонемент ($m)

Пример использования новых возможностей платформы 8.3.9 по низкоуровневой работе с двоичными данными для инкрементальной передачи файлов на сервер.

1 стартмани

04.10.2016    13587    53    mrstomak    21    

Несколько шаблонов для доработки типовых конфигураций

Практика программирования Инструментарий разработчика v8 v8::УФ Абонемент ($m)

Предлагаю несколько каркасов для создания новых объектов в типовых конфигурациях. Это выжимка из кода нескольких конфигураций, которая позволит быстро и красиво создавать и дорабатывать объекты метаданных с соблюдением идеологии исходной системы

1 стартмани

03.10.2016    37057    95    json    25    

HTTP-сервис: отчеты [Расширение]

Практика программирования Работа с интерфейсом v8 1cv8.cf Абонемент ($m)

Это HTTP-сервис, который возвращает почти любой отчет в HTML, XLSX или в JSON. Сохраните вариант отчета, получите на него ссылку и можно получить данные без захода в 1С. Работает в конфигурациях на основе БСП 2.3.3+, для отчетов на СКД и в 1С 8.3.8+

2 стартмани

30.08.2016    27245    137    Stepa86    15    

Недокументированное использование стандартных форм Upd.

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

Вам не хватает возможностей в платформе 1С или у Вас нет времени на углубленное изучение платформы 1С? Рассмотрены возможности использования стандартных форм, вызываемых из платформы.

1 стартмани

26.07.2016    28682    77    ZhokhovM    60    

БСП 2.3 и БСП 3.0: Просто про выполнение внешней обработки в фоне (c индикацией прогресса выполнения)

Инструментарий разработчика Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Абонемент ($m)

Простое пояснение о том, как сделать внешнюю обработку с фоновым выполнением и индикацией процесса для любой конфигурации на основе БСП 2.3.2. UPDATE 20/09/19: добавлен вариант обработки с индикацией процента выполнения и статусом выполнения для БСП 3.0.

1 стартмани

18.05.2016    62606    184    rozer    65    

Остатки на каждый день в запросе

Практика программирования Учет ТМЦ Учет ТМЦ v8 1cv8.cf УУ Абонемент ($m)

Запрос формирует остатки товаров на каждый день в пределах выбранного периода.

1 стартмани

26.04.2016    59869    19    arakelyan    19    

Еще один способ расчета остатков на каждый день в запросе

Математика и алгоритмы Практика программирования v8 Абонемент ($m)

Предлагается новый способ расчета остатков на каждый день (час, минуту, секунду) в запросе. Способ не требует предварительного формирования таблицы дат и также подходит для расчета курсов валют, цен номенклатуры и других периодических сведений на каждую дату периода. На больших объемах данных предлагаемый способ может превосходить по быстродействию ранее известные методы из-за линейной (в лучшем случае) зависимости трудоемкости от длины периода.

1 стартмани

24.04.2016    34990    49    ildarovich    23    

Вывод печатных форм с запросом данных в форму "Печать документов" из подсистемы БСП "Печать".

Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Абонемент ($m)

Все не раз видели, как в типовых конфигурациях, построенных на основе БСП (Библиотека стандартных подсистем), печатные формы, построенные на основе Табличного документа, выводятся в специальную форму "ПечатьДокументов". Эта форма входит в состав подсистемы "Печать" из БСП. При разработке своих печатных форм, иногда необходимо запросить у пользователя дополнительные данные необходимые для печати. Тут встает вопрос, как в этом случае вывести печатную форму в форму "Печать документа". В этой статье я рассмотрю, как реализовать вывод печатной формы в упомянутую форму из подсистемы "Печать", в случае если мы хотим перед выводом печатной формы запросить у пользователя дополнительные данные. Здесь будут рассмотрены два случая: когда реализуется печатная форма с использованием подсистемы "Дополнительные отчеты и обработки" и когда печатная форма добавляется в конфигурацию в режиме конфигуратора, т.е. вносятся изменения в типовую конфигурацию.

1 стартмани

29.03.2016    91546    181    lopatin    14    

Выполнение JavaScript кода из 1С в объекте Поле HTML Документа (HTML 5) и вызов события в 1С ПриНажатии

Практика программирования v8 1cv8.cf Россия Абонемент ($m)

Пример выполнения JS кода из 1С в Поле HTML Документа под управляемыми формами, с удобным получением результата в 1С(С помощью вызова привязанного события ПриНажатии к элементу ПолеHTMLДокумента)

1 стартмани

22.03.2016    82169    160    igo1    54    

Количество дней недели (понедельников/вторников/...) в заданном диапазоне одним запросом

Практика программирования v8 Абонемент ($m)

При реализации периодического авто-заполнения маршрутных листов по графику (недельному) необходимо было просчитать стоимость всего периода, с условием выездов только по определенным дням. Заморачиваться с обходом результата не хотелось. Пришлось написать "Небольшой" запрос.

1 стартмани

03.03.2016    18577    1    Alexander.Shvets    5    

Простые радости жизни программиста 1С: выбор типа значения

Работа с интерфейсом Практика программирования v8 1cv8.cf Абонемент ($m)

Предлагаемая в работе обработка включает обычную и управляемую формы, которые максимально точно реализуют функциональность системного диалога выбора типа в толстом клиенте обычное приложение (включая оформление диалога). Эти формы имеют дополнительные интерфейсные удобства и могут быть использованы в качестве альтернативных диалогов выбора типа.

1 стартмани

17.02.2016    50654    53    yuraos    17    

Отображение прогресса выполнения длительных операций в БСП и их отладка в текущем сеансе.

Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Абонемент ($m)

В статье описан способ исполнения длительных операций в конфигурациях, в которых используется библиотека стандартных подсистем, с визуализацией прогресса исполнения и отображения хода обработки данных. Также дается краткое описание процесса отладки длительных операций в текущем сеансе.

1 стартмани

17.02.2016    56148    179    balanton    23    

Яндекс.Деньги "Благотворительность"

Инструментарий разработчика Практика программирования v8 1cv8.cf Абонемент ($m)

Яндекс.Деньги теперь в 1С. Форма для приема благотворительных взносов. Форму легко сделать и вставить на любую страницу сайта или блога. Платежи будут приходить на ваш кошелек. На форме есть три способа платежа: из кошелька, с банковской карты, с баланса мобильного.

1 стартмани

16.02.2016    23644    8    Tatitutu    5    

Мастер рассылки e-mail 2.2 для управляемых форм

Практика программирования Email v8 v8::УФ ERP2 БП3.0 УТ11 Абонемент ($m)

Для пользователей: переделанный из старый разработки под 8.2 с использованием библиотеки Мастер рассылки e-mail 2.2 (ERP, УТ, БП) (Только управляемые формы), который теперь может запускаться под любой версией платформы с разрешенными или запрещенными модальными/синхронными вызовами в конфигурации. Также удобный выбор e-mail и их владельцев с помощью отбора динамического списка по любым критериям и галочки исключения.

1 стартмани

29.12.2015    37399    20    milkers    4    

Передача больших пакетов через веб-сервисы

Практика программирования Администрирование данных 1С Внешние источники данных v8 Абонемент ($m)

Реализация механизма передачи больших пакетов через веб-сервисы. С его помощью передать файл размером в несколько гигабайт не составит проблем.

1 стартмани

06.12.2015    57603    48    YPermitin    19