Reputation: 39
I wrote a piece of code in HANA and used the HIERARCHY_ANCESTORS function. However, it started giving me all sorts of OOM (Out of Memory) issues. I raised an OSS & provided all the details just to realize that it was an unidentified issue of the standard SAP function which will now be rectified in the next release. Now I do not want to delve on the HIERARCHY_ANCESTORS function, as I already lost a month communicating through the OSS. What I need is an alternative, which does not include any loops. Basically, I need the ancestors of all the leaf nodes (HIERARCHY_TREE_SIZE = 1) identified from the HIERARCHY function, without using loops. There can be over around 35k leaf nodes. The data size is over 80k records, and I have tried looping over the same earlier, and it severely degrades the performance, timing out after a certain point. My need is to wrap it up in less than 30s, like the HIERARCHY_ANCESTORS functions would.
I can perhaps create a recursive function to fetch all the ancestors of 1 leaf ID. But how would I use it inside a SQL query, so that the same function can then fetch the ancestors of all the requisite IDs?
Any help is appreciated from HANA POV. Thank you.
Upvotes: 2
Views: 1341
Reputation: 164
Consider the following hierarchy
The leaves and their ancestors are:
| NODE_ID | ANCESTOR |
| ------- | -------- |
| A010 | A |
| A10 | A |
| B | B |
| C0 | C |
To get there, you can use annother hierarchy function to produce the same behavior.
create COLUMN TABLE TSTHIERARCHY(
parent_id nvarchar(32),
node_id nvarchar(32),
val integer
);
INSERT INTO TSTHIERARCHY VALUES (NULL,'A',1);
INSERT INTO TSTHIERARCHY VALUES ('A','A0',2);
INSERT INTO TSTHIERARCHY VALUES ('A','A1',2);
INSERT INTO TSTHIERARCHY VALUES ('A0','A01',3);
INSERT INTO TSTHIERARCHY VALUES ('A01','A010',4);
INSERT INTO TSTHIERARCHY VALUES ('A1','A10',3);
INSERT INTO TSTHIERARCHY VALUES (NULL,'B',1);
INSERT INTO TSTHIERARCHY VALUES (NULL,'C',1);
INSERT INTO TSTHIERARCHY VALUES ('C','C0',2);
WITH t1 AS (SELECT * FROM HIERARCHY( SOURCE TSTHIERARCHY ))
SELECT leaves.NODE_ID, ancestors.NODE_ID AS ANCESTOR
FROM (
select NODE_ID, HIERARCHY_ROOT_RANK
FROM t1 WHERE HIERARCHY_RANK NOT IN (SELECT DISTINCT HIERARCHY_PARENT_RANK FROM t1)
) leaves
INNER join
( SELECT NODE_ID, HIERARCHY_RANK
FROM t1 WHERE HIERARCHY_RANK = HIERARCHY_ROOT_RANK
) ancestors
on (leaves.HIERARCHY_ROOT_RANK=ancestors.HIERARCHY_RANK)
Does that work ?
A simpler query exists to display the ancestor for all hierarchy members, not just leaf nodes:
SELECT NODE_ID,HIERARCHY_RANK,
FIRST_VALUE(NODE_ID) OVER (PARTITION BY HIERARCHY_ROOT_RANK ORDER BY hierarchy_level) AS ancestors
FROM HIERARCHY( SOURCE TSTHIERARCHY )
Upvotes: 0