Skip to main content
Announcements
Live today at 11 AM ET. Get your questions about Qlik Connect answered, or just listen in. SIGN UP NOW
cancel
Showing results for 
Search instead for 
Did you mean: 
Not applicable

Cumulative sum in script

Hi Qlikers,

i have a problem simple to understand but difficult to solve for me.

I have a Warehouse movements table with the movements of one year back (MOVEMENTS_1YB).

I need to make a cumulative sum of QTA_MOV_1YB grouped by CAUSAL_MOV_1YB,DATE_MOV_1YB and ITEM and ordered by DATE_MOV_1YB.

My goal is produce a field within the script called CUM_QTA_MOV_1YB.

I've attached the script that produce an error ('INVALID EXPRESSION') now.

MOVEMENTS_1YB:

LOAD

     ITEM,

     QTA_MOV_1YB,

     DATE_MOV_1YB,

     CAUSAL_MOV_1YB

RESIDENT WAREHOUSE_MOVEMENTS

WHERE DATE_MOV_1YB>=ADDMONTHS(DATE(TODAY()),-$(ROLLING_PERIOD));

CUMULATIVE_SUM:

LOAD

     ITEM,

     DATE_MOV_1YB,

     CAUSAL_MOV_1YB,

     SUM(QTA_MOV_1YB)+PEEK(CUM_QTA_MOV_1YB)        AS CUM_QTA_MOV_1YB

RESIDENT MOVEMENTS_1YB

GROUP BY CAUSAL_MOV_1YB,DATE_MOV_1YB,ITEM;

DROP TABLE MOVEMENTS_1YB;

Anybody can help me?

Thanks in advance.

1 Solution

Accepted Solutions
Oleg_Troyansky
Partner Ambassador/MVP
Partner Ambassador/MVP

Hi Michele,

A few comments:

1. Based on your desired output, it looks like you want to accumulate quantities just by Items, not by Item, Date, and Causal.

So, in this case, you should only compare  Item with the Previous(Item).

2. Based on our desired output, you need to add the cumulative "running total" in the same table with the movements, not in a separate table by ITEM - that would produce wrong results.

So, I think your script should look like this:

WAREHOUSE_MOVEMENTS_TEMP:

LOAD

    ITEM,

 

    DATE_MOV,

    MONTH_MOV,

 

    QTY_MOV,

    CAUSAL_MOV

RESIDENT

     MOV_MAG

ORDER BY

     ITEM ASC,DATE_MOV ASC,CAUSAL_MOV ASC;

DROP TABLE MOV_MAG;

WAREHOUSE_MOVEMENTS:

LOAD

    ITEM,

    DATE_MOV,

    MONTH_MOV,

 

    QTY_MOV,

    IF((

        Previous(ITEM)                       =    ITEM

        ),

            RangeSum(peek('CUM_QTA_MOV_1YB') , QTY_MOV),

                QTY_MOV)                                                         AS CUM_QTA_MOV_1YB

RESIDENT

     WAREHOUSE_MOVEMENTS_TEMP

ORDER BY

      ITEM,

      DATE_MOV,

     CAUSAL_MOV

;

DROP TABLE WAREHOUSE_MOVEMENTS_TEMP;

I also replaced a simple addition ( the plus sign) with a RangeSum, to protect it against an accidental NULL value...

Now you better buy my book 🙂

cheers,

Oleg Troyansky

View solution in original post

14 Replies
vinieme12
Champion III
Champion III

do you really need peek()??


just this would do


CUMULATIVE_SUM:

LOAD

     ITEM,

     DATE_MOV_1YB,

     CAUSAL_MOV_1YB,

     SUM(QTA_MOV_1YB)    AS CUM_QTA_MOV_1YB

RESIDENT MOVEMENTS_1YB

GROUP BY CAUSAL_MOV_1YB,DATE_MOV_1YB,ITEM;

DROP TABLE MOVEMENTS_1YB;

Vineeth Pujari
If a post helps to resolve your issue, please accept it as a Solution.
Oleg_Troyansky
Partner Ambassador/MVP
Partner Ambassador/MVP

Hi Michele,

in fact, you need a combination of peek() and previous(). With previous(), you can compare the current values of Causal, Date, and Item with the previous values and only if they are the same, then you'd accumulate the values, otherwise you'd start from zero.

Something like this:

IF(Previous(Causal)=Causal and Previous(Date)=Date and Previous(Item) = Item, peek('Cumulative_Qty') + Qty, Qty) as Cumulative_Qty


Notice that Previous() doesn't require single quote around the field name, while Peek() does. There is a reason for using Previous() in your comparison and Peek() in the calculation. I'm describing the process with a lot of detail in my book QlikView Your Business, also using this technique for the Inventory Analysis - check it out!

cheers,

Oleg Troyansky

ahaahaaha
Partner - Master
Partner - Master

Hi Michele,

Try

CUMULATIVE_SUM:

LOAD

    ITEM,

    DATE_MOV_1YB,

    CAUSAL_MOV_1YB,

   RangeSum(QTA_MOV_1YB, Peek('CUM_QTA_MOV_1YB')) as CUM_QTA_MOV_1YB

RESIDENT MOVEMENTS_1YB

GROUP BY CAUSAL_MOV_1YB,DATE_MOV_1YB,ITEM;

DROP TABLE MOVEMENTS_1YB;

Regards,

Andrey

Oleg_Troyansky
Partner Ambassador/MVP
Partner Ambassador/MVP

One more thought... I just noticed your GROUP BY clause. If you just need to aggregate all transactions by these three fields, then you don't need to use Peek() and Previous(). I assumed from your description that you need to know the CUMULATIVE value at the time of each individual transaction (that's common in Inventory Analysis). If you need that, then you don't need to use GROUP BY - just reload the data, sorted by your 3 key fields and a timestamp, and use Peek() and Previous() for the CUMULATIVE calculation.


Cheers,

Oleg Troyansky

Oleg_Troyansky
Partner Ambassador/MVP
Partner Ambassador/MVP

Folks,

Peek() won't work in combination with GROUP BY - you can only use one of the two, but not both techniques at the same time.

Not applicable
Author

Unfortunately it doesn't work fine.

An error message like "AGGREGATION EXPRESSIONS REQUIRED BY GROUP BY CLAUSE" is appeared.

Not applicable
Author

I've followed your suggestion using

"IF(Previous(Causal)=Causal and Previous(Date)=Date and Previous(Item) = Item, peek('Cumulative_Qty') + Qty, Qty) as Cumulative_Qty" without GROUP BY and the script works fine but the Cumulative_Qty field is empty.

which is the other method?

Oleg_Troyansky
Partner Ambassador/MVP
Partner Ambassador/MVP

That's exactly my point (read above) - you can use either GROUP BY with sum(), or Peek and Previous, but without Group By.

The GROUP BY clause requires using aggregation functions like SUM().

In order to follow the technique that I suggested, remove the GROUP BY clause.

Not applicable
Author

I'm sorry but there isn't an accumulation with this method.