Do not input private or sensitive data. View Qlik Privacy & Cookie Policy.
Skip to main content

Announcements
Qlik Open Lakehouse is Now Generally Available! Discover the key highlights and partner resources here.
cancel
Showing results for 
Search instead for 
Did you mean: 
Abhilash_N
Contributor
Contributor

To Create Cluster column based on sales_share% for every 3 customers for every product

Hi All,

Iam new to qlik view i want to create cluster column

Rules to create Cluster column

Rule1: for each product minimum 3 customers  are to be cluster

Rule2: in that cluster we need to check sales_share% of each customer should be < 70% if any of customer sales_share% is >70% we need add  next customer to the existing cluster so on until we get sales_share%<70% in that cluster for customer

Rule3: in that product any of customers left unclustered i.e(one or two customers left) those customers are to be appended to the last cluster 

 

Input data

 

ProductsCustomersIDSales
Product1cust1125260
Product1cust2216700
Product1cust338560
Product1cust442672
Product1cust55368
Product1cust66312
Product1cust77312
Product1cust88312
Product1cust9956
Product1cust101056
Product1cust111156
Product1cust121256
Product1cust13130
Product1cust14140
Product2cust111,923
Product2cust221,572
Product2cust33 1,123
Product2cust44  695
Product2cust55  168
Product2cust66  112
Product2cust77  112
Product2cust88  56
Product2cust99  56
Product2cust1010  28
Product2cust1111  28
Product2cust1212  15
Product2cust1313   -  

 

Output data

 

ProductsCustomersIDSalesOutput_culsterSales_Share%Avg sales
Product1cust1125260150.00%16840
Product1cust2216700133.06%16840
Product1cust338560116.94%16840
Product1cust442672267.20%795.2
Product1cust5536829.26%795.2
Product1cust6631227.85%795.2
Product1cust7731227.85%795.2
Product1cust8831227.85%795.2
Product1cust9956325.00%56
Product1cust101056325.00%56
Product1cust111156325.00%56
Product1cust121256325.00%56
Product1cust1313000.00%0
Product1cust1414000.00%0
Product2cust111922.81141.64%1539.183
Product2cust221571.93134.04%1539.183
Product2cust331122.81124.32%1539.183
Product2cust44695263.94%271.75
Product2cust55168217.23%272
Product2cust66112210.30%272
Product2cust77112210.30%272
Product2cust8856.14330.62%36.67
Product2cust9956.14330.62%37
Product2cust101028.07315.31%37
Product2cust111128315.27%37
Product2cust12121538.18%37
Product2cust1313000.00%0

 

 

Thanks&Regards

Abhilash

1 Solution

Accepted Solutions
Kushal_Chawda

This is my attempt

 

 

Data:
LOAD
    Products,
    Customers,
    ID,
    if(Sales>0,Sales,0) as Sales
FROM [lib://Data/Data.qvd]
(qvd);

New:
Load *,
     RowNo() as Row
Resident Data
where Sales>0
Order by Products,Sales desc;

let vProduct = FieldValue('Products',1);

let vMinRow = Peek('Row',0,'New');

let vMaxRow = Peek('Row',-1,'New');

let vRowStart ='$(vMinRow)';let vRowEnd ='$(vMinRow)'+2;

let vCluster=1;

let vNextClusterEndProduct = Peek('Products','$(vRowEnd)'+2,'New');

let vNextClusterEndProductRow = Peek('Row','$(vRowEnd)'+2,'New');

let vNextRowToClusterEndProduct = Peek('Products','$(vRowEnd)','New');

let vNextRowToClusterEnd = Peek('Row','$(vRowEnd)','New');

Final:
Load * Inline [
Temp ];

do while vRowEnd <= vMaxRow

Loop:
NoConcatenate
Load ID,
     Products,
     Row,
     Sales
Resident New
where Row>='$(vRowStart)' and Row<='$(vRowEnd)';

let vCheckProduct = Peek('Products',-1,'Loop');

if '$(vCheckProduct)'<>'$(vNextRowToClusterEndProduct)' or '$(vNextRowToClusterEnd)' > '$(vMaxRow)' then

Left Join(Loop)
Load sum(Sales) as Cluster_Sales,
    Avg(Sales) as Avg_Sales
Resident Loop;

Percentage:
Load ID,
     Avg_Sales,
     Products,
     Sales,
     num(Sales/Cluster_Sales,'#0.00%') as Sales_Share
Resident Loop;

Drop Table Loop;

Concatenate(Final)
Load *,
     '$(vCluster)' as Cluster
Resident Percentage;

Drop Table Percentage;

let vProduct = '$(vCheckProduct)';

let vCluster = 1;

let vRowStart = '$(vNextRowToClusterEnd)';

let vRowEnd ='$(vNextRowToClusterEnd)'+2;

ElseIf '$(vCheckProduct)'<>'$(vNextClusterEndProduct)' or '$(vNextClusterEndProductRow)' > '$(vMaxRow)' then

NextCluster:
Load Products,
     Row
Resident New
where Products='$(vNextClusterEndProduct)' and (Row>='$(vNextClusterEndProductRow)'-3 and Row<='$(vNextClusterEndProductRow)');

let vCheckProductNextClusterRow = Peek('Row',0,'NextCluster');

let vRowEnd =if('$(vNextClusterEndProductRow)' > '$(vMaxRow)','$(vMaxRow)','$(vCheckProductNextClusterRow)'-1);

Drop Tables Loop,NextCluster;

Let vCheckProductNextClusterRow=null();

Else 

Left Join(Loop)
Load sum(Sales) as Cluster_Sales,
    Avg(Sales) as Avg_Sales
Resident Loop;

Percentage:
Load ID,
     Avg_Sales,
     Products,
     Sales,
     num(Sales/Cluster_Sales,'#0.00%') as Sales_Share,
     if(Sales/Cluster_Sales>0.7,1,0) as Flag
Resident Loop;

Drop Table Loop;

Check_Percent:
Load if(sum(Flag)>0,1,0) as Percent_Check_Flag
Resident Percentage;

let vPercent_Check = Peek('Percent_Check_Flag',0,'Check_Percent');

Drop Table Check_Percent;

if '$(vPercent_Check)' =1 then

let vRowEnd = '$(vRowEnd)'+1;

Drop Table Percentage;

else

Concatenate(Final)
Load *,
     '$(vCluster)' as Cluster
Resident Percentage;

Drop Table Percentage;

let vRowStart = '$(vRowEnd)'+1;

let vRowEnd = '$(vRowEnd)'+3;

let vCluster = '$(vCluster)'+1;

let vPercent_Check = null();

EndIf

EndIf

let vNextClusterEndProductRow = '$(vRowEnd)'+3;

let vNextClusterEndProduct = if(isnull(Peek('Products','$(vRowEnd)'+2,'New')),'$(vCheckProduct)',Peek('Products','$(vRowEnd)'+2,'New'));

let vNextRowToClusterEnd = '$(vRowEnd)'+1;

let vNextRowToClusterEndProduct = if(isnull(Peek('Products','$(vRowEnd)','New')),'$(vCheckProduct)',Peek('Products','$(vRowEnd)','New'));

Loop

Drop Tables New;

Concatenate(Final)
Load *,
     0 as Cluster,
     0 as Avg_Sales,
     0 as Sales_Share
Resident Data
Where Sales=0;

Drop Table Data;

Drop Field Temp;

 

 

Annotation 2020-07-26 213524.png

Annotation 2020-07-26 213551.png

 

View solution in original post

5 Replies
sunny_talwar

Is this something you need to do in the script or front end?

Kushal_Chawda

Can you also share scenario where customer share is > 70%?

Abhilash_N
Contributor
Contributor
Author

yes we need to do on script level

Abhilash_N
Contributor
Contributor
Author

In the above if we see in product1 for cust4,5,6  cust4_share%=2672/(2672+368+312)=0.79 so it is >70%or>0.7 so we need to add another customers to that cluster '2' until the share% decreases to below 70%or0.7

Kushal_Chawda

This is my attempt

 

 

Data:
LOAD
    Products,
    Customers,
    ID,
    if(Sales>0,Sales,0) as Sales
FROM [lib://Data/Data.qvd]
(qvd);

New:
Load *,
     RowNo() as Row
Resident Data
where Sales>0
Order by Products,Sales desc;

let vProduct = FieldValue('Products',1);

let vMinRow = Peek('Row',0,'New');

let vMaxRow = Peek('Row',-1,'New');

let vRowStart ='$(vMinRow)';let vRowEnd ='$(vMinRow)'+2;

let vCluster=1;

let vNextClusterEndProduct = Peek('Products','$(vRowEnd)'+2,'New');

let vNextClusterEndProductRow = Peek('Row','$(vRowEnd)'+2,'New');

let vNextRowToClusterEndProduct = Peek('Products','$(vRowEnd)','New');

let vNextRowToClusterEnd = Peek('Row','$(vRowEnd)','New');

Final:
Load * Inline [
Temp ];

do while vRowEnd <= vMaxRow

Loop:
NoConcatenate
Load ID,
     Products,
     Row,
     Sales
Resident New
where Row>='$(vRowStart)' and Row<='$(vRowEnd)';

let vCheckProduct = Peek('Products',-1,'Loop');

if '$(vCheckProduct)'<>'$(vNextRowToClusterEndProduct)' or '$(vNextRowToClusterEnd)' > '$(vMaxRow)' then

Left Join(Loop)
Load sum(Sales) as Cluster_Sales,
    Avg(Sales) as Avg_Sales
Resident Loop;

Percentage:
Load ID,
     Avg_Sales,
     Products,
     Sales,
     num(Sales/Cluster_Sales,'#0.00%') as Sales_Share
Resident Loop;

Drop Table Loop;

Concatenate(Final)
Load *,
     '$(vCluster)' as Cluster
Resident Percentage;

Drop Table Percentage;

let vProduct = '$(vCheckProduct)';

let vCluster = 1;

let vRowStart = '$(vNextRowToClusterEnd)';

let vRowEnd ='$(vNextRowToClusterEnd)'+2;

ElseIf '$(vCheckProduct)'<>'$(vNextClusterEndProduct)' or '$(vNextClusterEndProductRow)' > '$(vMaxRow)' then

NextCluster:
Load Products,
     Row
Resident New
where Products='$(vNextClusterEndProduct)' and (Row>='$(vNextClusterEndProductRow)'-3 and Row<='$(vNextClusterEndProductRow)');

let vCheckProductNextClusterRow = Peek('Row',0,'NextCluster');

let vRowEnd =if('$(vNextClusterEndProductRow)' > '$(vMaxRow)','$(vMaxRow)','$(vCheckProductNextClusterRow)'-1);

Drop Tables Loop,NextCluster;

Let vCheckProductNextClusterRow=null();

Else 

Left Join(Loop)
Load sum(Sales) as Cluster_Sales,
    Avg(Sales) as Avg_Sales
Resident Loop;

Percentage:
Load ID,
     Avg_Sales,
     Products,
     Sales,
     num(Sales/Cluster_Sales,'#0.00%') as Sales_Share,
     if(Sales/Cluster_Sales>0.7,1,0) as Flag
Resident Loop;

Drop Table Loop;

Check_Percent:
Load if(sum(Flag)>0,1,0) as Percent_Check_Flag
Resident Percentage;

let vPercent_Check = Peek('Percent_Check_Flag',0,'Check_Percent');

Drop Table Check_Percent;

if '$(vPercent_Check)' =1 then

let vRowEnd = '$(vRowEnd)'+1;

Drop Table Percentage;

else

Concatenate(Final)
Load *,
     '$(vCluster)' as Cluster
Resident Percentage;

Drop Table Percentage;

let vRowStart = '$(vRowEnd)'+1;

let vRowEnd = '$(vRowEnd)'+3;

let vCluster = '$(vCluster)'+1;

let vPercent_Check = null();

EndIf

EndIf

let vNextClusterEndProductRow = '$(vRowEnd)'+3;

let vNextClusterEndProduct = if(isnull(Peek('Products','$(vRowEnd)'+2,'New')),'$(vCheckProduct)',Peek('Products','$(vRowEnd)'+2,'New'));

let vNextRowToClusterEnd = '$(vRowEnd)'+1;

let vNextRowToClusterEndProduct = if(isnull(Peek('Products','$(vRowEnd)','New')),'$(vCheckProduct)',Peek('Products','$(vRowEnd)','New'));

Loop

Drop Tables New;

Concatenate(Final)
Load *,
     0 as Cluster,
     0 as Avg_Sales,
     0 as Sales_Share
Resident Data
Where Sales=0;

Drop Table Data;

Drop Field Temp;

 

 

Annotation 2020-07-26 213524.png

Annotation 2020-07-26 213551.png