Qlikview聚合

Qlikview aggregation

我有一个 table 如下所示。每个日期都有一个产品。我想按产品汇总并结转总数。但是合计限制为0,对于每一天,每一件产品,我要汇总结转汇总。

Date product Amount
06/Jan/2021 a 300
05/Jan/2021 a 200
05/Jan/2021 b 500
04/Jan/2021 a -100
04/Jan/2021 b 1100
03/Jan/2021 a -500
03/Jan/2021 b -900
02/Jan/2021 a 200
02/Jan/2021 b 500
01/Jan/2021 a 100

对于最新日期,我希望看到如下输出:

Date product total
06/Jan/2021 a 500
06/Jan/2021 b 1600

查看下面的脚本。 我注释了代码以解释每个步骤。

如果重新加载脚本,结果 table 将是:

基本思路是:

  • 按产品和日期(升序)排列记录
  • 加载已排序的 table 聚合记录(按产品)
  • 如果总和为< 0则return0,否则继续聚合
  • 一旦我们有了聚合,就会找到每个产品的最大日期并标记这些记录。最大日期记录将包含总金额(每个产品)
  • 过滤标记的记录并在最后加载它们table

带注释的加载脚本:

RawData:
Load * inline [
Date       , product, Amount
06/Jan/2021, a      , 300
05/Jan/2021, a      , 200
05/Jan/2021, b      , 500
04/Jan/2021, a      , -100
04/Jan/2021, b      , 1100
03/Jan/2021, a      , -500
03/Jan/2021, b      , -900
02/Jan/2021, a      , 200
02/Jan/2021, b      , 500
01/Jan/2021, a      , 100
];

NoConcatenate

// Order the data by product and date in ascending order
OrderedData:
Load
  date(date#(Date, 'DD/MMM/YYYY')) as Date, // convert to date
  product,
  Amount
Resident 
  RawData
Order By 
  product,
  Date asc
;

// we dont need RawData table anymore
Drop Table RawData;

// CalculatedAmount calculation/logic:
// * if the current value for product is not equal to the prvious value
//   get the current amount. This the case where the producs are "switched"
// * if the sum of the current Amount value + the previous CalculatedAmount value
//   is less than 0 then return 0
// * for the rest of the cases - return the aggregated amount - current Amount
//   added to the previous CalculatedAmount
CalculatedAmount:
Load 
  Date,
  product,
  Amount,
  if( product <> peek('product'), Amount,
    if( Amount + peek('CalculatedAmount') < 0, 0,
  Amount + peek('CalculatedAmount')
  )) as CalculatedAmount
Resident 
  OrderedData
;

// we dont need OrderedData anymore
Drop Table OrderedData;

// use the CalculatedAmount table to find the max date for each product
// these records are containing the total amount for each product
// flag these records with 1 and join the result table back to
// CalculatedAmount table
join (CalculatedAmount)
Load 
  max(Date) as Date,
  product,
  1 as isTotalAmount
Resident
  CalculatedAmount
Group By 
  product
;

// the final table - filter CalculatedAmount table to return
// only the records for which isTotalAmount = 1
TotalAmount:
Load 
  Date,
  product,
  CalculatedAmount as TotalAmount
Resident
  CalculatedAmount
Where
  isTotalAmount = 1
;

// we dont need CalculatedAmount table anymore
Drop Table CalculatedAmount;