Skip to main content
Announcements
Join us at Qlik Connect for 3 magical days of learning, networking,and inspiration! REGISTER TODAY and save!
cancel
Showing results for 
Search instead for 
Did you mean: 
jbrodmann
Partner - Contributor II
Partner - Contributor II

Count offers per rank and date

Hello, i have here a tricky one.

At first i have an offer table. The relevant columns and example data is shown in the following table:

offer_idproduct_idoffer_datemerchantprice
1101/01/2019A5.00
2101/01/2019B7.00
3101/01/2019C4.00
4101/01/2019OWN_CLIENT6.00
5201/01/2019A20.00
6201/01/2019B19.00
7201/01/2019C21.00
8201/01/2019OWN_CLIENT18.00
9101/02/2019A6.00
10101/02/2019B7.00
11101/02/2019C4.00
12101/02/2019OWN_CLIENT8.00
13201/02/2019A19.00
14201/02/2019B20.00
15201/02/2019C21.00
16201/02/2019OWN_CLIENT22.00

 

I want to get my (OWN_CLIENT) rankings for each day. The result would look like:

DateRankoffer count
01/01/201911
01/01/201921
01/02/201942

 

In the next step all ranks above 5 should be grouped as Rank '6+'.

My solution so far:

Dimension 1: 

offer_date

Dimension 2:

=aggr( {1<merchant={'OWN_CLIENT'}>} // first aggr to get the group by product and date
	ONLY(
        aggr( // second aggr to rank all offers per product and date
            {$ + 1<merchant={'OWN_CLIENT'}>}
            if (rank(-min(price),1,1) <= 5, // group ranks above 5 to 6+
                rank(-min(price),1,1)
                , Dual('6+', 6)),
            offer_date,
            product_id,
            offer_id
        )
    ), 
    offer_date,
    product_id
)

Measure:

Count(distinct product_id)

This works so far and is giving me all correct rankings. 

The disadvantage is, this solution is very slow. Maybe someone has a better, not so awkward solution for this szenario?

Greetings, Jens

Labels (1)
1 Solution

Accepted Solutions
sunny_talwar

The only thing you can really simplify without modifying the script is to simplify your if statement to this

=Aggr(
	Only({1<merchant={'OWN_CLIENT'}>}
        Aggr(
            RangeMin(Rank(-Min({$ + 1<merchant = {'OWN_CLIENT'}>} price), 1, 1), Dual('6+', 6))
            , offer_date, product_id, offer_id)
    )
, offer_date, product_id)

Otherwise, another option is to calculate the Rank part in the script as it seems that it doesn't have to change based on selection of any sorts because you use 1 in your expression's set analysis.

View solution in original post

2 Replies
sunny_talwar

The only thing you can really simplify without modifying the script is to simplify your if statement to this

=Aggr(
	Only({1<merchant={'OWN_CLIENT'}>}
        Aggr(
            RangeMin(Rank(-Min({$ + 1<merchant = {'OWN_CLIENT'}>} price), 1, 1), Dual('6+', 6))
            , offer_date, product_id, offer_id)
    )
, offer_date, product_id)

Otherwise, another option is to calculate the Rank part in the script as it seems that it doesn't have to change based on selection of any sorts because you use 1 in your expression's set analysis.

jbrodmann
Partner - Contributor II
Partner - Contributor II
Author

Thank you for the fast reply.

The RangeMin function is great, it makes the whole thing more readable.

Unfortunately this have to react on filters (the inner aggregation) and pre calculation in the load script is not possible.

There are 500+ merchants and 50,000+ offer, it seems calculating rankings for this amount of data and each day is not very fast.

My second attempt is to count all offers that are cheaper than my per product:

=aggr(
    RangeMin(
     	count(distinct if(price<own_price, offer_id)) + 1
        , Dual('6+', 6)
    ),
    offer_date,
    product_id)

That is giving me the same values like the rank function, but a bit faster.

It seams the amount of data is the problem here.