Skip to main content
Announcements
Qlik Connect 2024! Seize endless possibilities! LEARN MORE
cancel
Showing results for 
Search instead for 
Did you mean: 
Alyona
Contributor III
Contributor III

How to create pivot table with dynamic number of columns from straight in script

Hi, Qlik experts!

I need your help! 

I have the following straight table - clients and their active contracts: 

Client #Contract 
Client 1Contract 111
Client 1Contract 222
Client 2Contract 333
Client 3Contract 444
Client 3Contract 555
Client 3Contract 666

 

Based on it I need to create pivot table in the script - for each client I need to show all its active contracts in 1 row (each contract should be in separate column): 

Client #Contract #1Contract #2Contract #3
Client 1Contract 111Contract 222 
Client 2Contract 333  
Client 3Contract 444Contract 555Contract 666

 

Is it possible to create this pivot table with dynamically defining the number of columns (using loops or other techniques)? 

Important nuance is that we don't know what is the maximum number of active contracts one client could have (in my example - it is 3 contracts, but in reality it could be today 5 contracts, tomorrow 3 and the day after tomorrow 20). 

 

Please give me advise how to do this. 

 

Thanks in advance, 

Alyona

1 Solution

Accepted Solutions
Alyona
Contributor III
Contributor III
Author

Hi, Marcus!

Thanks, but I am not sure that generic load could help me with this task. 

 

Actually, I have found the solution: 

//Calculate for each Client the count of active contracts: 
[Clients_and_contracts]:
LOAD
[Client #],
COUNT([Contract ]) AS ActiveContractCount
RESIDENT InitialTable
GROUP BY [Client #]
;

//Add details by contracts 
LEFT JOIN (Clients_and_contracts)
LOAD
[Client #],
[Contract ]
RESIDENT InitialTable
;


RENAME TABLE [Clients_and_contracts] TO [Clients_and_contracts_old];


Clients_and_contracts:
NoConcatenate
LOAD
*,
IF([Client #] <> Previous([Client #]), 1, PEEK('ContractNum')+1) AS ContractNum,
RowNo() AS RowNum
RESIDENT Clients_and_contracts_old
WHERE
ActiveContractCount > 1 //need only client which have more than 1 active contract
ORDER BY [Client #], [Contract] asc
;

 

DROP TABLE InitialTable, Clients_and_contracts_old;


//Calculate the max number of parallel active contracts
MaxActiveContractCount:
LOAD
Max(ActiveContractCount) as MaxActiveContractCount
RESIDENT Clients_and_contracts
;

LET vMaxActiveContractCount = PEEK('MaxActiveContractCount ');


PIVOT:
LOAD
DISTINCT [Client #],
PEEK('Contract',RowNum-1,'Clients_and_contracts') AS [Contract #1]
RESIDENT Clients_and_contracts
WHERE ActiveContractCount>=2 AND ContractNum = 1 
;


FOR i = 2 TO $(vMaxActiveContractCount)
LEFT JOIN (TEST)
LOAD
DISTINCT [Client #],
PEEK('Contract,RowNum+$(i)-2,'Clients_and_contracts') AS 'Contract #$(i)'
RESIDENT Clients_and_contracts
WHERE ActiveContractCount>=$(i) and ContractNum = 1
;
NEXT i


DROP TABLE MaxActiveContractCount, Clients_and_contracts;

View solution in original post

3 Replies
marcus_sommer

This could be done with The-Generic-Load.

- Marcus

Alyona
Contributor III
Contributor III
Author

Hi, Marcus!

Thanks, but I am not sure that generic load could help me with this task. 

 

Actually, I have found the solution: 

//Calculate for each Client the count of active contracts: 
[Clients_and_contracts]:
LOAD
[Client #],
COUNT([Contract ]) AS ActiveContractCount
RESIDENT InitialTable
GROUP BY [Client #]
;

//Add details by contracts 
LEFT JOIN (Clients_and_contracts)
LOAD
[Client #],
[Contract ]
RESIDENT InitialTable
;


RENAME TABLE [Clients_and_contracts] TO [Clients_and_contracts_old];


Clients_and_contracts:
NoConcatenate
LOAD
*,
IF([Client #] <> Previous([Client #]), 1, PEEK('ContractNum')+1) AS ContractNum,
RowNo() AS RowNum
RESIDENT Clients_and_contracts_old
WHERE
ActiveContractCount > 1 //need only client which have more than 1 active contract
ORDER BY [Client #], [Contract] asc
;

 

DROP TABLE InitialTable, Clients_and_contracts_old;


//Calculate the max number of parallel active contracts
MaxActiveContractCount:
LOAD
Max(ActiveContractCount) as MaxActiveContractCount
RESIDENT Clients_and_contracts
;

LET vMaxActiveContractCount = PEEK('MaxActiveContractCount ');


PIVOT:
LOAD
DISTINCT [Client #],
PEEK('Contract',RowNum-1,'Clients_and_contracts') AS [Contract #1]
RESIDENT Clients_and_contracts
WHERE ActiveContractCount>=2 AND ContractNum = 1 
;


FOR i = 2 TO $(vMaxActiveContractCount)
LEFT JOIN (TEST)
LOAD
DISTINCT [Client #],
PEEK('Contract,RowNum+$(i)-2,'Clients_and_contracts') AS 'Contract #$(i)'
RESIDENT Clients_and_contracts
WHERE ActiveContractCount>=$(i) and ContractNum = 1
;
NEXT i


DROP TABLE MaxActiveContractCount, Clients_and_contracts;

sbash
Contributor
Contributor

where is the TEST table created?

LEFT JOIN (TEST)