Skip to main content
hic
Former Employee
Former Employee

Last week I wrote about how the Above() function can be used for calculating rolling averages and other accumulations. There is however also an alternative method for doing the same thing:

The As-Of table.

When you use the Above() function, you fetch a number from other rows in a chart or Aggr() table. The As-Of table is slightly different in this respect: It is not a transient table created by an object or an expression – instead it is a real table in the data model.

The idea is to create a secondary month field – the AsOfMonth - that links to multiple real months.

 

Fields.png

 

In the example above, you can see that ‘2015 Oct’ links to several preceding months, and each Month in turn links to several rows in a fact table. This means that a specific transaction will be linked to several AsOfMonths.

In the data model, the As-Of table should appear as a separate calendar table that links to the existing primary calendar table:

 

DataModel.png

 

One way to create this table is the following:

First, make sure that you in your master calendar have a field “Month” that is defined as the first date of the month, e.g.

 

Date(MonthStart(Date),'YYYY MMM') as Month,

 

Then add the following lines at the end of the script:

 

// ======== Create a list of distinct Months ========
tmpAsOfCalendar:
Load distinct Month
  Resident [Master Calendar] ;

// ======== Cartesian product with itself ========
Join (tmpAsOfCalendar)
Load Month as AsOfMonth
  Resident tmpAsOfCalendar ;

// ======== Reload, filter and calculate additional fields ========
[As-Of Calendar]:
Load Month,
  AsOfMonth,
  Round((AsOfMonth-Month)*12/365.2425) as MonthDiff,
  Year(AsOfMonth)-Year(Month) as YearDiff
  Resident tmpAsOfCalendar
      Where AsOfMonth >= Month;

Drop Table tmpAsOfCalendar;

 

Once this table has been created, you can use the AsOfMonth as dimension in charts where you want rolling averages and accumulations.

If you as measure use

 

Sum({$<YearDiff={0}>} Sales)

 

you will get a yearly accumulation – year-to-date up until the day of the script run.

 

Yearly accumulation.png

 

If you instead use

 

Sum({$<MonthDiff={"<6"}>} Sales) / Count(distinct {$<MonthDiff={"<6"}>} Month)

 

you will get a 6-month rolling average:

 

Rolling average.png

And finally, if you use

 

Sum({$<MonthDiff={0}>} Sales)

 

You will get the real, non-accumulated numbers.

I have made the Set Analysis expressions based on two fields: YearDiff and MonthDiff. However, for clarity it could be a good idea to add flags in the As-Of table, so that the Set Analysis expressions become even simpler, e.g.

 

If(MonthDiff=0,1,0) as IsSameMonth,
If(YearDiff=0,1,0) as IsSameYear,
If(MonthDiff<6,1,0) as IsRolling6,

 

Summary: The As-Of table is a good way to calculate rolling averages and accumulations.

 

HIC

 

Further reading related to this topic:

The Above Function

Accumulations

Calculating rolling n-period totals, averages or other aggregations

103 Comments
Not applicable

Love this!

0 Likes
18,966 Views
Not applicable

Great article!!

I use it and it works perfectly. It is very useful.

Thanks

0 Likes
18,966 Views
acardella
Partner - Creator
Partner - Creator

Thanks for sharing!

0 Likes
18,966 Views
reinholdgraf
Creator
Creator

Hi.

Wanted to use this function in Qliksense.

When loading, the following error-message occurs:

Table not found

tmpAsOfCalendar:

...

...

The script is as follows:

// Kalenderfunktion ergänzen

autoCalendar:

Declare Field Definition Tagged '$date'

    Fields

    Year($1) As Jahr Tagged '$year',

        Ceil(Month(Datum)/3) as Quartal,

        Month($1) As Monat Tagged '$month',

        Year($1) & '-' & Month($1) as [Jahr-Monat],

        Year($1) & '-' & Ceil(Month(Datum)/3) as [Jahr-Quartal],

        Week($1) AS Woche Tagged '$week',

        weekday($1) As Wochentag Tagged '$weekday',

        Date($1) As Datum Tagged ('$date', '$day'),

        Date(MonthStart($1),'YYYY-MMM')as xMonth,

        DayNumberOfYear($1) as Jahrestag Tagged ('$numeric');

Derive Fields From Fields Datum Using autoCalendar;

// create a list of distinct months

tmpAsOfCalendar:

  Load distinct xMonth

    Resident autoCalendar;

// cartesian product with itself       

    Join(tmpAsOfCalendar)

    Load xMonth as AsOfMonth

    Resident tmpAsOfCalendar;

// reload, filter and calculate additional fields

[As-Of Calendar]:

  Load xMonth,

    AsOfMonth,

    Round((AsOfMonth-Month)*12/365.2425) as MonthDiff,

    Year(AsOfMonth)-Year(xMonth) as YearDiff,

    Resident tmpAsOfCalendar

    where AsOfOmonth >= Month;

    Drop Table tmpAsOfCalendar;

What am I doing wrong ?

I am new to QS, so it might just be a beginners fault 😉

Reinhold

0 Likes
18,964 Views
stevedark
Partner Ambassador/MVP
Partner Ambassador/MVP

If you put an Exit Script; in before the first tmpAsOfCalendar line - does the autoCalendar table exist with the rows in you are expecting?  From there it all looks fine.

0 Likes
18,900 Views
reinholdgraf
Creator
Creator

Putting in "Exit Script;" delivers no data at all.

I think, the problem is, that the master calendar is not built with LOAD; so it likely is built, when the field "Datum" is loaded later ?

0 Likes
18,900 Views
stevedark
Partner Ambassador/MVP
Partner Ambassador/MVP

Perhaps - can you try moving the As Of code right to the end of the load script after everything else is loaded?

0 Likes
18,900 Views
reinholdgraf
Creator
Creator

Yes - same result (table not found)

0 Likes
18,900 Views
reinholdgraf
Creator
Creator

I think, the problem is, how the Master Calendar is built.

I don't know, how Henric's Master Calendar has been built. - This might help

0 Likes
18,900 Views
stevedark
Partner Ambassador/MVP
Partner Ambassador/MVP

It would have just been in a LOAD statement, where Month is either a field in the main fact table or in a separate calendar table.  There are loads of scripts online for creating these.

Try Googling "QlikView Calendar Script"


Steve

0 Likes
18,900 Views