Qlik - 如何使用 Set Analysis 求和直到最后一个可用数据记录而不是最后一个日历日期

Qlik - How to use Set Analysis to sum until the last available record with data instead of the last calendar date

我现在的表情是这样的:

Sum({$<[Calendar Date] = {
<=$(=Date(MonthEnd(Date(Today()))))
>=$(=Date(AddMonths(MonthStart(Date(Today())), - 12)))"}>} [Amount])

数据是这样的:

Companies   MonthYear   Amount
Company1    201701  10000
Company1    201612  20000
Company2    201701  -
Company2    201612  -
Company2    201611  35000
Company2    201610  17000
Company3    201701  -
Company3    201612  50000
Company3    201611  10000
Company3    201610  24000
Company3    201609  40000
Company3    201608  -
Company3    201607  -
Company3    201606  32000
Company3    201605  18000

这就是我想要达到的效果:

示例:

但是因为我使用 Today() 作为我的限制,所以我显示了以下内容:(这不是我想要实现的)

示例:

我需要如何更改表达式,以便我的仪表板将 [Amount] 字段与每个公司的最后一个可用月份的数据相加,直到该日期之前的 12 个月?

PS: 今天() = 2016 年 1 月 23 日

这可能有用...

=Sum({<MonthYear={'$(=Max(MonthYear))'}>}Amount)

我想出了我必须使用的表达方式:

我只需要将 Today() 替换为可用金额的最大月份

Sum({$< [Calendar Date] = {"
<=$(=Date(MonthEnd(Date(Date(MonthEnd(Date(Max(Aggr(Max({$<[Calendar Date] = 
{"<=$(=Date(MonthEnd(Date(Today()))))"}, [Amount] = {"<>0"}>}
[Calendar Date]), [Companies])))))))))
>=$(=Date(AddMonths(MonthStart(Date(Date(MonthEnd(Date(Max(
Aggr(Max({$<[Calendar Date] = {"<=$(=Date(MonthEnd(Date(Today()))))"}, [Amount] = {"<>0"}>}
[Calendar Date]), [Companies]))))))), -12)))"}>} [Amount])

我看到你已经回答了你自己的问题,但想提供另一个建议。

如果您希望汇总不同时间段(即去年)的值,并且只想查看去年,则可以通过将一些标志放入你的数据模型。我知道这不是集合分析,但如果它向外扩展,它会提高你的 UI 的性能,因为你正在使用许多复杂的函数来实现我们可以在模型中简单地完成的事情。

这个加载脚本做了三件事:

  1. 加载您的数据(我必须格式化日期以便 QV 能够识别它)
  2. 获取每个公司的金额的最新日期
  3. 迭代创建最近 12 个月的列表,并将其作为标志字段加入到原始 table (Flag_LatestYear)

然后,在您的集合分析中,您可以在图表中使用以下表达式(它们将 "companies" 字段作为维度)。

Sum({$<Flag_LatestYear={1}>}Amount)

这是金额字段通常求和的比较,并与集合分析(它删除了我添加的附加记录 - 这是故意超出范围的)

Normal Sum vs Set Analysis for the latest 12 months available for each company

这是加载脚本。

// Load raw data - preceding load used to clean up date. I added a new row at the bottom that was deliberately out of the date range it should pick up
OriginalTable:
LOAD
    Companies,
    DATE(DATE#([Calendar Date],'YYYYMM')) AS [Calendar Date],
    Amount;
LOAD * INLINE [
    Companies,   Calendar Date,   Amount
    Company1,    201701,  10000
    Company1,    201612,  20000
    Company2,    201701,  -
    Company2,    201612,  -
    Company2,    201611,  35000
    Company2,    201610,  17000
    Company3,    201701,  -
    Company3,    201612,  50000
    Company3,    201611,  10000
    Company3,    201610,  24000
    Company3,    201609,  40000
    Company3,    201608,  -
    Company3,    201607,  -
    Company3,    201606,  32000
    Company3,    201605,  18000
    Company3,    201405,  50000
];


// Grab the max dates from the loaded table
TEMP_MaxDate:
LOAD
    Companies,
    MAX([Calendar Date]) AS CalendarDateMax
RESIDENT OriginalTable
WHERE Amount > 0
GROUP BY Companies;

// This is a cheat, but I've put it in as your dataset is small. It'll iterate through and create joining records for every month in the last 12, per company
// I'll use this to join back to the OriginalTable for my flag. Note that it joins on two fields - a key would be better
LEFT JOIN (OriginalTable)
LOAD
    Companies,
    DATE(AddMonths(CalendarDateMax,-iterNo() + 1)) AS [Calendar Date],
    1 AS Flag_LatestYear
RESIDENT TEMP_MaxDate
WHILE AddYears(CalendarDateMax,-1) <= AddMonths(CalendarDateMax,-iterNo() + 1);

// Clean up and remove the temp table
DROP TABLE TEMP_MaxDate;

一如既往,还有其他方法可以实现这一目标!让我知道这是否有帮助。