Расчет даты последней покупки в скрипте Qlik Sense/Qlikview

Автор HalLex, 15 октября 2017, 06:10:22

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

HalLex

Доброго времени суток!

В своём примере расчета числа повторных покупок, Андрей Свиридов приводит такой вот код:


//***Автор скрипта Свиридов Андрей
ДанныеПродаж:
LOAD НомерСчета,
ДатаСчета,
КодКлиента,
sum(Сумма)as Сумма
FROM
Продажи.qvd (qvd)
Group By НомерСчета, ДатаСчета, КодКлиента;

//Используем резидентную загрузку для формирования таблицы с уникальными идентификаторами клиентов
Temp:
LOAD Distinct
КодКлиента as CustomerID
Resident ДанныеПродаж;
//В переменнуя Score будет записываться дата последнего счета по каждому клиенту

Set Score = 0;

//Первый цикл FOR перебирает каждого клиента в таблеце Temp

FOR i=0 to NoOfRows('Temp')-1
//В переменную Customer записывается идентификатор клиента на каждой итерации цикла
Let Customer = Peek('CustomerID',$(i),'Temp');

//Таблица Temp1 содержит даты всех счетов по каждому клиенту
Temp1:
NoConcatenate

Load
ДатаСчета as ДатаСчета1
Resident ДанныеПродаж
Where КодКлиента = '$(Customer)';//Каждый клиент попадает в параметр отбора

//Второй цикл вычисляет самую позднюю дату счета
FOR l=0 to NoOfRows('Temp1')-1
IF(Peek('ДатаСчета1',$(l),'Temp1')>$(Score)) then
LET Score = Peek('ДатаСчета1',$(l),'Temp1');//Дата счета записывается в переменную Score
ENDIF
NEXT;

DROP Table Temp1;//больше данные этой таблицы не нужны, она заполнится следующим клиентом на следующей итерации

//Формируем из данных переменных таблицу

Temp2:
LOAD
'$(Customer)' as Client,
'$(Score)' as LastDate
AutoGenerate (1);

SET Score = 0;//Присваиваем переменной значение 0, необходимо для последующей работы цикла

NEXT;

//присоединяем дополнительное поле к таблице по ключу "КодКлиента"

Left Join (ДанныеПродаж)
LOAD
Client as КодКлиента,
LastDate as ДатаПоследнегоСчета
Resident Temp2;

//Избавляемся от лишних таблиц

DROP Table Temp;
DROP Table Temp2;

//Создаем новую таблицу используя резидентную загрузку

Temp3:
NoConcatenate
LOAD
НомерСчета,
ДатаСчета,
КодКлиента,
Сумма,
ДатаПоследнегоСчета,
If(ДатаПоследнегоСчета<MonthEnd(AddMonths(Today(),-2)),1,0) as ПотеряныйКлиент,//Клиенты не совершившие покупку более месяца
If(ДатаПоследнегоСчета<MonthEnd(AddMonths(Today(),-2)),Num(Month(ДатаПоследнегоСчета)),) as МесяцПотериКлиента,// Месяц в котором клиент совершал последнюю покупку
If(ДатаПоследнегоСчета>MonthEnd(AddMonths(Today(),-2)),Num(Month(ДатаСчета)),) as МесяцНаличияКлиента//Месяц в котором клмент остается клиентом
Resident ДанныеПродаж;

//Убираем таблицу
DROP Table ДанныеПродаж;

//Переименовывыем таблицу
RENAME Table Temp3 to ДанныеПродаж;


В данном цикле, вычисляем самую позднюю дату счета. Подскажите пожалуйста, как преобразовать цикл, что бы вычислить наоборот, первую дату покупки?
Спасибо!!

FOR l=0 to NoOfRows('Temp1')-1
IF(Peek('ДатаСчета1',$(l),'Temp1')>$(Score)) then
LET Score = Peek('ДатаСчета1',$(l),'Temp1');//Дата счета записывается в переменную Score
ENDIF

admin

Привет, для чего использовать циклы?

Можно ведь сделать запрос на ID клиента и максимальную дату, т.о. мы получаем таблицу с ИД клиента и датой последней покупки. Т.е. получаем то же самое но намного быстрее и легче.

HalLex

А Вы могли бы привести пример такого кода (запроса)?

admin

LOAD
КодКлиента as CustomerID,
max(Дата) As ДатаКрайнейСделки
Resident ДанныеПродаж
group by КодКлиента;

HalLex

Решение прекрасно подошло для задачи, большое спасибо.

Подскажите, а есть решение, если мне требуется найти минимальный и максимальный интервал в днях, между покупками для покупателя?

admin

Сначала рассчитайте интервалы между покупками, затем рассчитывайте min, max.
Почитайте про previous & peek в хелпе

HalLex

Подскажите, а как выполнять расчет именно для конкретного клиента из таблицы, а не все по порядку?

Test1:
Load
КодКлиента,
Date(ДатаСчета) as ДатаСчета1,
Previous (Date(ДатаСчета)) as Previuos,
ДатаСчета - Previous (Date(ДатаСчета)) as Разница
Resident DistClients
Order by КодКлиента;

Если брать простое использование функции, вычитается все по порядку. Соответственно, каждое последнее вычитание, это последняя покупка одного клиента и первая другого.

admin

Используйте проверку
load
...
if(КодКлиента=Previous(КодКлиента),
ДатаСчета - Previous (Date(ДатаСчета))) as Разница
...
Resident DistClients
Order by КодКлиента;

HalLex

Test1:
Load
КодКлиента,
Date(ДатаСчета) as ДатаСчета1,
Previous(ДатаСчета) as Previous,
if(КодКлиента = Previous(КодКлиента), ДатаСчета-Previous(Date(ДатаСчета))) as Разница
Resident DistClients
Order by КодКлиента, ДатаСчета;


MinMax:
Load
КодКлиента,
If(КодКлиента, Min(Разница)) as МинДнейМеждЗак,
If(КодКлиента, Max(Разница)) as МаксДнейМеждЗак
Resident Test1
Group by КодКлиента;

Для нахождения минимальной и максимальной разницы, решил так же использовать if. Максимум считает для каждого покупателя, а минимум только для некоторых, избирательно. Подскажите, в чем ошибка?

admin

Странно, что он вообще считает.
Зачем условия при группировке?
Просто вычисляйте минимум и максимум для клиента.

HalLex

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




MinMax << Test1
Ошибка скрипта: Invalid expression
Произошла следующая ошибка:
Invalid expression
Ошибка произошла здесь:
MinMax:
Load
КодКлиента,
If(КодКлиента, Min(Разница)) as МинДнейМеждЗак,
If(КодКлиента, Max(Разница)) as МаксДнейМеждЗак
Resident Test1
Произошла следующая ошибка:
Invalid expression
Ошибка произошла здесь:
?
Данные не загружены. Исправьте ошибку и повторите загрузку.

admin

мин и макс работают только при группировке.

HalLex

Load
КодКлиента,
Min(Разница) as МинДнейМеждЗак,
Max(Разница) as МаксДнейМеждЗак
Resident Test1
Group By КодКлиента;

Спасибо!!!

HalLex

Возник еще вопрос по ходу.... Не могу сообразить, как мне объяснить функции autonumber, пронумеровать дату первой покупки для каждого покупателя. Есть код клиента, есть даты его покупок, есть дата первой покупки. Идея в том, что бы присвоить "1" первой его покупке, для определения количества новых покупателей за выбранную дату покупки. Либо пронумеровать каждую дату покупки (1,2,3.....), но так для каждого покупателя, начиная с "1".

HalLex

НумерацияПокупок:
   LOAD
   Distinct (КодКлиента) as ClientID,
   ДатаСчета as DateSale,
   AutoNumber(ДатаСчета,[КодКлиента])
   resident DistClients;

Вроде как разобрался)

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