В этой статье речь пойдет про накопительный календарь и календарь с флагами для расчета LFL показателей, например, продажи за последние 90 дней текущего месяца к продажам за аналогичный период предыдущего года (т.е. 90 дней прошлого года).
Для начала рассмотрим упрощенный пример LFL Календаря.
LFL Календарь Qlik Sense (для расчета показателей год к году)
//=========================================================================== // Автор & Дата: Шамаев Иван 2019.06.01 // Описание: Создание календаря на основе максимальной и минимальной дате // ************************************************************************** // Изменение: // <номер изменения, дата, автор> - <описание> //=========================================================================== // Получаем из поля Дата минимальное и максимальное значения [TEMP Максимальная Минимальная Дата]: LOAD Min(FieldValue('Дата',RecNo())) As [Минимальная Дата], Max(FieldValue('Дата',RecNo())) As [Максимальная Дата] AutoGenerate FieldValueCount('Дата'); // Минимальную и максимальную даты помещаем в переменные, // для того, чтобы использовать их в условии While Let пНачалоКалендаря_Число = Num(Peek('Минимальная Дата', 0, 'TEMP Максимальная Минимальная Дата')); Let пОкончаниеКалендаря_Число = Num(Peek('Максимальная Дата', 0, 'TEMP Максимальная Минимальная Дата')); Let пСегодняДата_Число = Num(Today()); // Удаляем временную таблицу DROP Table [TEMP Максимальная Минимальная Дата]; // Создаем набор дат в промежутке от минимальной до максимальной даты [TEMP Набор дат в интервале MinDate - MaxDate]: LOAD Date($(пНачалоКалендаря_Число) + IterNo() - 1) as [TEMP Дата] AutoGenerate 1 While $(пНачалоКалендаря_Число) + IterNo() -1 <= $(пОкончаниеКалендаря_Число); // Формируем таблицу с календарем LFL в моделе Qlik Sense [Календарь]: Load *, if(Дата<=Date($(пСегодняДата_Число)) and Дата>=AddMonths(Date($(пСегодняДата_Число)),-6),1) As [Текущий год 180 Дней], if(Дата<=AddYears(Date($(пСегодняДата_Число)),-1) and Дата>=AddMonths(AddYears(Date($(пСегодняДата_Число)),-1),-6),1) As [Предыдущий год 180 Дней], if(Дата<=Date($(пСегодняДата_Число)) and Дата>=AddMonths(Date($(пСегодняДата_Число)),-3),1) As [Текущий год 90 Дней], if(Дата<=AddYears(Date($(пСегодняДата_Число)),-1) and Дата>=AddMonths(AddYears(Date($(пСегодняДата_Число)),-1),-3),1) As [Предыдущий год 90 Дней], if(Дата<=Date($(пСегодняДата_Число)) and Дата>=AddMonths(Date($(пСегодняДата_Число)),-1),1) As [Текущий год 30 Дней], if(Дата<=AddYears(Date($(пСегодняДата_Число)),-1) and Дата>=AddMonths(AddYears(Date($(пСегодняДата_Число)),-1),-1),1) As [Предыдущий год 30 Дней], if(Дата<=Date($(пСегодняДата_Число)) and Дата>=Date($(пСегодняДата_Число)-7),1) As [Текущий год 7 Дней], if(Дата<=Date($(пСегодняДата_Число)-7) and Дата>=Date($(пСегодняДата_Число)-14),1) As [Предыдущие 7 Дней], if(Дата<=Date($(пСегодняДата_Число)) and Дата>=MakeDate(Year(Date($(пСегодняДата_Число)))),1) As [Текущий год], if(Дата<=AddYears(Date($(пСегодняДата_Число)),-1) and Дата>=MakeDate(Year(AddYears(Date($(пСегодняДата_Число)),-1))),1) As [Прошлый год] ; Load Date([TEMP Дата]) As Дата, Date([TEMP Дата],'DD MMMM YYYY') As [Дата длинный месяц], Text(Date([TEMP Дата],'WWWW MMM YYYY')) As [День недели МесяцГод], 'Кв'& Ceil(Num(Month([TEMP Дата]))/3) As Квартал, 'Кв'& Ceil(Num(Month([TEMP Дата]))/3) & '-' & Year([TEMP Дата]) As КварталГод, Text(Date([TEMP Дата],'YYYY.MM')) As [Год Месяц], Text(Date([TEMP Дата],'MMM YYYY')) As [Месяц Год], Year([TEMP Дата]) As Год, Year([TEMP Дата])&'.'&Week([TEMP Дата]) As [Год Неделя], Week([TEMP Дата]) As Неделя, Day([TEMP Дата]) As День Resident [TEMP Набор дат в интервале MinDate - MaxDate]; Drop Table [TEMP Набор дат в интервале MinDate - MaxDate];
Принскрин скрипта LFL календаря Qlik Sense (Календарь с флагами на даты):

Теперь для того, чтобы отобразить продажи за период можно использовать в Set Analysis предварительно рассчитанные флаги. Следующие примеры будут использовать модификатор 1 для того, чтобы исключить установленные в модели фильтры (т.е. на полном множестве данных):
//Продажи за 180 дней в текущем году: sum({1<[Текущий год 180 Дней]={1}>} [Продажи руб]) //Продажи за 180 дней в прошлом году (аналогичный период годом ранее): sum({1<[Предыдущий год 180 Дней]={1}>} [Продажи руб])
Если Вам нужно учитывать выборки модели, то рекомендуется проигнорировать выборки по полям календаря. Делается это следующим образом (через запятую перечисляются поля календаря и ставится знак равно, это означает, что по этому полю мы игнорируем установленные выборки):
//Продажи за 180 дней в текущем году: sum({<[Текущий год 180 Дней]={1},[Дата длинный месяц]=,Дата=,[День недели МесяцГод]=,Квартал=,КварталГод=,[Год Месяц]=,[Месяц Год]=,Год=,[Год Неделя]=,Неделя=,День=>} [Продажи руб]) //Продажи за 180 дней в прошлом году (аналогичный период годом ранее): sum({<[Предыдущий год 180 Дней]={1},[Дата длинный месяц]=,Дата=,[День недели МесяцГод]=,Квартал=,КварталГод=,[Год Месяц]=,[Месяц Год]=,Год=,[Год Неделя]=,Неделя=,День=>} [Продажи руб])
Еще один вариант календаря Qlik Sense (поправил первый вариант)
//=========================================================================== // Автор & Дата: Шамаев Иван 2020.05.01 // Описание: Создание календаря на основе максимальной и минимальной дате // ************************************************************************** // Изменение: // <номер изменения, дата, автор> - <описание> //=========================================================================== // Получаем из поля Дата минимальное и максимальное значения [TEMP Максимальная Минимальная Дата]: LOAD Min(FieldValue('Дата',RecNo())) As [Минимальная Дата], Max(FieldValue('Дата',RecNo())) As [Максимальная Дата] AutoGenerate FieldValueCount('Дата'); // Минимальную и максимальную даты помещаем в переменные, // для того, чтобы использовать их в условии While Let пНачалоКалендаря_Число = Num(Peek('Минимальная Дата', 0, 'TEMP Максимальная Минимальная Дата')); Let пОкончаниеКалендаря_Число = Num(Peek('Максимальная Дата', 0, 'TEMP Максимальная Минимальная Дата')); Let пСегодняДата_Число = Num(Today()); // Удаляем временную таблицу DROP Table [TEMP Максимальная Минимальная Дата]; // Создаем набор дат в промежутке от минимальной до максимальной даты [TEMP Набор дат в интервале MinDate - MaxDate]: LOAD Date($(пНачалоКалендаря_Число) + IterNo() - 1) as [TEMP Дата] AutoGenerate 1 While $(пНачалоКалендаря_Число) + IterNo() -1 <= $(пОкончаниеКалендаря_Число); // Формируем таблицу с календарем LFL в моделе Qlik Sense [Календарь]: Load *, //Генерация флагов для более простого сравнительного анализа по периодам if(Дата<=Date($(пСегодняДата_Число)) and Дата>Date($(пСегодняДата_Число)-360),1) As [Флаг Текущий год 360 Дней], if(Дата<=AddYears(Date($(пСегодняДата_Число)),-1) and Дата>Date(AddYears(Date($(пСегодняДата_Число)),-1)-360),1) As [Флаг Предыдущий год 360 Дней], if(Дата<=Date($(пСегодняДата_Число)) and Дата>Date($(пСегодняДата_Число)-180),1) As [Флаг Текущий год 180 Дней], if(Дата<=AddYears(Date($(пСегодняДата_Число)),-1) and Дата>Date(AddYears(Date($(пСегодняДата_Число)),-1)-180),1) As [Флаг Предыдущий год 180 Дней], if(Дата<=Date($(пСегодняДата_Число)) and Дата>Date($(пСегодняДата_Число)-90),1) As [Флаг Текущий год 90 Дней], if(Дата<=AddYears(Date($(пСегодняДата_Число)),-1) and Дата>Date(AddYears(Date($(пСегодняДата_Число)),-1)-90),1) As [Флаг Предыдущий год 90 Дней], if(Дата<=Date($(пСегодняДата_Число)) and Дата>Date($(пСегодняДата_Число)-30),1) As [Флаг Текущий год 30 Дней], if(Дата<=AddYears(Date($(пСегодняДата_Число)),-1) and Дата>Date(AddYears(Date($(пСегодняДата_Число)),-1)-30),1) As [Флаг Предыдущий год 30 Дней], if(Дата<=Date($(пСегодняДата_Число)) and Дата>Date($(пСегодняДата_Число)-7),1) As [Флаг Текущие 7 дней], if(Дата<=Date($(пСегодняДата_Число)-7) and Дата>Date($(пСегодняДата_Число)-14),1) As [Флаг Предыдущие 7 Дней], if(Дата<=Date($(пСегодняДата_Число)) and Дата>=MakeDate(Year(Date($(пСегодняДата_Число)))),1) As [Флаг Текущий год], if(Дата<=AddYears(Date($(пСегодняДата_Число)),-1) and Дата>=MakeDate(Year(AddYears(Date($(пСегодняДата_Число)),-1))),1) As [Флаг Прошлый год], if(Дата>=MonthStart($(пСегодняДата_Число)) and Дата<=Date($(пСегодняДата_Число)),1) As [Флаг Текущий MTD], if(Дата>=AddMonths(MonthStart($(пСегодняДата_Число)),-1) and Дата<=AddMonths(Date($(пСегодняДата_Число)),-1),1) As [Флаг Предыдущий MTD] ; Load Date([TEMP Дата]) As Дата, Date([TEMP Дата],'DD MMMM YYYY') As [Дата длинный месяц], Text(Date([TEMP Дата],'WWWW MMM YYYY')) As [День недели МесяцГод], 'Кв'& Ceil(Num(Month([TEMP Дата]))/3) As Квартал, 'Кв'& Ceil(Num(Month([TEMP Дата]))/3) & '-' & Year([TEMP Дата]) As КварталГод, Text(Date([TEMP Дата],'YYYY.MM')) As [Год Месяц], Text(Date([TEMP Дата],'MMM YYYY')) As [Месяц Год], Year([TEMP Дата]) As Год, Year([TEMP Дата])&'.'&Week([TEMP Дата]) As [Год Неделя], Week([TEMP Дата]) As Неделя, Day([TEMP Дата]) As День Resident [TEMP Набор дат в интервале MinDate - MaxDate]; Drop Table [TEMP Набор дат в интервале MinDate - MaxDate];
Пример формулы с использованием флагов:
sum({<[Флаг Текущие 7 дней]={1}>} [Продажи, руб]) sum({<[Флаг Предыдущие 7 Дней]={1}>} [Продажи, руб])