Определение даты первого счета Клиента

Автор Oleg, 11 марта 2017, 10:16:21

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

Oleg

Казалось бы, воспользуйся ты функцией min(Дата счета) и прекращай заниматься ерундой в субботу вечером. Но не все так просто..
Есть еще правило: первым счетом Клиента считается такой счет, дата выставления которого больше даты выставления предыдущего счета на этого Клиента на 365 дней и более.
Пожалуй, это можно было бы реализовать на стадии скрипта загрузки, но в силу того что Счета связаны с Клиентами через несколько таблиц и наличия еще одного правила "на вырост"(в конце), я этого не делаю..
Пытаюсь выкрутить это через анализ множество, но все тщетно.
Пример не работающей формулы, которая по моей задумке должна была бы сработать:
max(
aggr({1<Номер счета = {"=rangesum(Дата счета,-below(Дата счета))>365"}>}
Дата счета,
Клиент, Дата счета(Numeric,Descending)))
)

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

Правило на вырост: первым счетом Клиента по Продукту считается такой счет, дата выставления которого больше даты выставления предыдущего счета на этого Клиента по этому же продукту на 365 дней.
По идее должно выглядеть как-то так:
max(
aggr({1<Номер счета = {"=rangesum(Дата счета,-below(Дата счета))>365"}>}
Дата счета,
Клиент, Продукт, Дата счета(Numeric,Descending)))
)

Совсем уже извелся с этой задачей :(

admin

Привет.

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

aggr() с множествами - отличные помощники, но не там где много записей или мало ресурсов.

millik

Цитата: admin от 11 марта  2017, 10:41:43  
aggr() с множествами - отличные помощники, но не там где много записей или мало ресурсов.
И даже там где ресурсов хватает. Агрегации и расчеты на лету очень сильно грузят проц. И нагрузка растет в геометрической прогрессии от увеличения объема обрабатываемых данных.

Oleg

Благодарю за советы!
Буду пробовать.
Долго я конечно отписываюсь. Только нашел время снова посетить форум.

millik

#4
Я конечно на своих данных, но вот накидал такой вариант без расчета в скрипте.

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

И так имеем две таблицы. Первая - рабочая, вторая уже с агрегацией.
Как вариант:


В первой таблице:
1) Карта - измерение
2) Дата - измерение
3) Дата - уже мера, но просто без обработки
4) Дней с прошлой покупки - высчитываем шаг дат прошлой меры.
[Дата]-Above([Дата])
5) Дней > 60 - а вот тут уже смотрим где шаг больше допустимого. Проверяем на Null, он будет вообще при первой покупке и второе условие уже на количество дней. Если условие выполнено, то записываем дату, если нет то Null. Обязательно Null, а не 0 или "". Т.к. 0 и "" - значения и они участвует во всяких Min/Max/Avg, а Null игнорится)
If(IsNull([Дата]-Above([Дата])) Or ([Дата]-Above([Дата]))>60,[Дата],Null())

Ну а во второй таблице уже играемся с агрегацией и придумываем что хотим получить на выходе. Например:
1) Карта - измерение
2) Мин дата (сама первая попкупка)
Date(Min(Aggr(IsNull([Дата]-Above([Дата])) Or ([Дата]-Above([Дата]))>60,[Дата],Null()),[Карта],[Дата])))
3) Макс дата (последнее возвращение клиента)
Date(Max(Aggr(IsNull([Дата]-Above([Дата])) Or ([Дата]-Above([Дата]))>60,[Дата],Null()),[Карта],[Дата])))
4) Кол возвращений клиента
Count(Aggr(IsNull([Дата]-Above([Дата])) Or ([Дата]-Above([Дата]))>60,[Дата],Null()),[Карта],[Дата]))


millik

И это пока не очень сложные агрегации, должно всё нормально считать.

У меня вот в оборачиваемости Aggr() в Aggr() с Aggr() в Set Analysis. И ничего считает понемногу. Ограничил только условия для расчета таблиц, чтобы народ не выбирал все периоды по всем товарам, ато тогда точно всё виснет.

Oleg

Цитата: millik от 23 июня  2017, 11:37:23  
И это пока не очень сложные агрегации, должно всё нормально считать.

У меня вот в оборачиваемости Aggr() в Aggr() с Aggr() в Set Analysis. И ничего считает понемногу. Ограничил только условия для расчета таблиц, чтобы народ не выбирал все периоды по всем товарам, ато тогда точно всё виснет.

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

Мое почтение :)

Яндекс.Метрика