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

Announcements
Join us in Toronto Sept 9th for Qlik's AI Reality Tour! Register Now
cancel
Showing results for 
Search instead for 
Did you mean: 
Not applicable

How to build Product Hierarchy based on Product ID

Hi Everyone,

I want to build product hierarchy structure based on Product ID. I have Product ID from table1. I want to produce table2.

Product ID
A.A.A.A.A
B.B.B.B.B
A.B.C
B.A
C.B.F.G
A.A.B.C
Product IDLevel1Level2Level3Level4Level5
A.A.A.A.AAA.AA.A.AA.A.A.AA.A.A.A.A
B.B.B.B.BBB.BB.B.BB.B.B.BB.B.B.B.B
A.B.CAA.BA.B.C
B.ABB.A
C.B.F.GCC.BC.B.FC.B.F.G
A.A.B.CAA.AA.A.BA.A.B.C

Thank you very much for help!

1 Solution

Accepted Solutions
settu_periasamy
Master III
Master III

Hi,

May be try this in a dynamic way

T1:
LOAD *,Len([Product ID]) as Len;
LOAD * inline [
Product ID
A.A.A.A.A
B.B.B.B.B
A.B.C
B.A
C.B.F.G
A.A.F.G
]
;

  Temp:
LOAD Max(Len) as Len Resident T1;
Let vMaxLen=Peek('Len')+1;
DROP Table Temp;

Let v1='';
for i= 1 to vMaxLen step 2
j=Ceil(i/2);
New:
$(v1)
LOAD
[Product ID],
if(Len(
[Product ID])>=$(i), Left([Product ID],$(i)),'') as Level$(j)
Resident T1;
Let v1='Left Join(New)';

NEXT i

DROP Table T1;


Edited: Red color highlighted

Capture.JPG

View solution in original post

17 Replies
Clever_Anjos
Employee
Employee

Maybe

LOAD

[Product ID],

subfield([Product ID],'.',1) as Level1,

subfield([Product ID],'.',1) & '.' & subfield([Product ID],'.',2) as Level2,

subfield([Product ID],'.',1) & '.' & subfield([Product ID],'.',2) & '.' & subfield([Product ID],'.',3) as Level3,

and so on

Not applicable
Author

Thank you - Clever.

I think it got close. But A.B.C stoped at level 3. I don't want it show on level 4.

Please see attached qvw.

Appreciate!

Not applicable
Author

forgot attach my qvw. Here it is. Thanks.

Clever_Anjos
Employee
Employee

Please use an if to test, for example:

if(subfield([Product ID],'.',4) <> '',subfield([Product ID],'.',1) & '.' & subfield([Product ID],'.',2) & '.' & subfield([Product ID],'.',3)& '.' & subfield([Product ID],'.',4)) as Level4,

Not applicable
Author

Thanks - Clever!

The product level will increase in the future. Is there a way to automatically add level to this table?

settu_periasamy
Master III
Master III

Hi,

May be try this in a dynamic way

T1:
LOAD *,Len([Product ID]) as Len;
LOAD * inline [
Product ID
A.A.A.A.A
B.B.B.B.B
A.B.C
B.A
C.B.F.G
A.A.F.G
]
;

  Temp:
LOAD Max(Len) as Len Resident T1;
Let vMaxLen=Peek('Len')+1;
DROP Table Temp;

Let v1='';
for i= 1 to vMaxLen step 2
j=Ceil(i/2);
New:
$(v1)
LOAD
[Product ID],
if(Len(
[Product ID])>=$(i), Left([Product ID],$(i)),'') as Level$(j)
Resident T1;
Let v1='Left Join(New)';

NEXT i

DROP Table T1;


Edited: Red color highlighted

Capture.JPG

Clever_Anjos
Employee
Employee

A not optimized option, maybe someone can bring us a better idea:

t:

LOAD

  [Product ID],

  SubStringCount([Product ID],'.')+1 as HowManyLevels

FROM

[https://community.qlik.com/thread/218664]

(html, codepage is 1252, embedded labels, table is @2);

let max=0;

for i = 0 to NoOfRows('t') - 1

  let h = Peek('HowManyLevels',i,'t');

  let max = RangeMax(h,max);

  let p = Peek('Product ID',i,'t');

  temp:load null() as n AutoGenerate 1;

  for j = 1 to $(h)

  Concatenate(temp)

  LOAD

  '$(p)' as [Product ID],

  left('$(p)',Index('$(p)','.',$(j))-1)  as Level$(j)

  AutoGenerate 1;

  next

next;

Final:

LOAD

  [Product ID],

  MinString(Level1) as Level1

Resident temp

where len([Product ID])>0

group by [Product ID];

for i = 1 to max

  LEFT join(Final)

  LOAD

  [Product ID],

  MinString(Level$(i)) as Level$(i)

  Resident temp

  where len([Product ID])>0

  group by [Product ID];

next;

drop Table temp;

Clever_Anjos
Employee
Employee

Another solution using generic (and later rejoin)

t:

LOAD

  [Product ID],

  SubStringCount([Product ID],'.')+1 as HowManyLevels

FROM

[https://community.qlik.com/thread/218664]

(html, codepage is 1252, embedded labels, table is @2);

let max=0;

for i = 0 to NoOfRows('t') -1

  let h = Peek('HowManyLevels',i,'t');

  let max = RangeMax(h,max);

  let p = Peek('Product ID',i,'t');

  temp:load null() as n AutoGenerate 0;

  for j = 1 to $(h)

  Concatenate(temp)

  LOAD

  '$(p)' as [Product ID],

  'Level$(j)' as [Level],

  left('$(p)',Index('$(p)','.',$(j))-1)  as Value

  AutoGenerate 1;

  next

next;

drop Field n;

drop Table t;

Final:

Generic LOAD

[Product ID],

Level,

Value

Resident temp;

drop Table temp;

LET vLoop = NoOfTables() - 1;

//Rename first table name

RENAME Table Final.Level1 to Final;

FOR i = 1 to vLoop

LET vCurrentTable = 'Final.Level'& ($(i) + 1);

Outer Join(Final)

LOAD  *

Resident $(vCurrentTable);

DROP Table $(vCurrentTable);

NEXT

Not applicable
Author

Thank you very much - settu_periasamy and Clever.

Appreciate you provide such a very smart way to build my hierarchy structure.

Best regards.