Запрос по изменению оборотов

Автор Харлампий Дымба, 11 мая 2025, 01:06

« назад - далее »

Пиит

Цитата
Не) ...это прям будет паровоз из уходящих в даль ДатаДок<>
)
Зато весь этот паровоз поедет целиком на скл сервер, и черный запрос станет чуточку светлее ))

Злоп

Нет у дбф никакого плана запроса.
тупо берется запись и прогоняется по тексту запроса (упрощенно).

Харлампий Дымба

Цитата: Пиит от 11 мая 2025, 20:33Зато весь этот паровоз поедет целиком на скл сервер, и черный запрос станет чуточку светлее ))
Так и вышло - в SQL паровоз из элементарных условий уделывает НайтиЗначение(). Принадлежит() работает значительно медленнее.
В ДБФ сильно быстрее всех работает Условие(Дата в СписокДат), а вот паровоз работает даже медленнее, чем Принадлежит(). А аутсайдер - НайтиЗначение().
Понять это не возможно, но по крайней мере, нужный результат я получил.
Буду собирать 2 паровозика типа Условие((ДатаДок<='05.03.25')или(ДатаДок>='07.03.25')и(ДатаДок<='12.03.25')) для включаемых и исключаемых дат и выбирать какой покороче.

Сборка получилась такой:
Функция глВернутьУсловиеПоДатамСтрокой(Знач СписокДат,НачалоПериодаОтбора,КонецПериодаОтбора,УсловиеНе=0) Экспорт
    //СписокДат - должен содержать неповторяющиеся непустые даты
    ВсегоДат=СписокДат.РазмерСписка();
    Если ВсегоДат=0 Тогда Возврат "" КонецЕсли;//пустой список смысла не имеет, даже если УсловиеНе=1
    Если ВсегоДат=КонецПериодаОтбора-НачалоПериодаОтбора+1 Тогда Возврат "" КонецЕсли;//все даты входят в список отбора - условие не делаем
    
    СписокДат.Сортировать();
    Результат="";
    ПредНачало=СписокДат.ПолучитьЗначение(1);
    ПредДата=ПредНачало-1;
    Для СчДат=1 По ВсегоДат+1 Цикл
        ДатаПром=?(СчДат>ВсегоДат,Дата(0),СписокДат.ПолучитьЗначение(СчДат));
        Если ДатаПром<>ПредДата+1 Тогда
            Если ПредНачало=ПредДата Тогда
                Результат=Результат+?(Результат="","","или")+"(ДатаДок='"+ПредДата+"')"
            ИначеЕсли ПредНачало=НачалоПериодаОтбора Тогда
                Результат=Результат+?(Результат="","","или")+"(ДатаДок<='"+ПредДата+"')" 
            ИначеЕсли ПредДата=КонецПериодаОтбора Тогда
                Результат=Результат+?(Результат="","","или")+"(ДатаДок>='"+ПредНачало+"')"
            Иначе    
                Результат=Результат+?(Результат="","","или")+"(ДатаДок>='"+ПредНачало+"')и(ДатаДок<='"+ПредДата+"')"
            КонецЕсли;
            ПредНачало=ДатаПром;
        КонецЕсли;    
        ПредДата=ДатаПром;
    КонецЦикла;
    Возврат ?(Результат="","",РазделительСтрок+"Условие("+?(УсловиеНе=1,"НЕ("+Результат+")",Результат)+");"); 
КонецФункции   

Вызов типа такого:
Условие1=глВернутьУсловиеПоДатамСтрокой(СписокВключаемыхДат,ВыбНачПериода,ВыбКонПериода);
Условие2=глВернутьУсловиеПоДатамСтрокой(СписокИсключаемыхДат,ВыбНачПериода,ВыбКонПериода,1);
ТекстЗапроса=ТекстЗапроса+?(СтрДлина(Условие1)>СтрДлина(Условие2),Условие2,Условие1);//возьмем условие покороче

Ну и подытожу: весь этот изврат понадобился, чтобы минимальными затратами и без особых потерь производительности заменить неработающий в SQL констракт Условие (Дата в СписокДат). Ну и просто - было интересно.
Спасибо всем и отдельный респект Пииту.