Given the table
ID PARENT_ID STRVAL SUBTYPE SUBVAL 0 null Chicago location city 1 0 Best Buy building bestbuy 2 0 Walmart building walmart 3 0 Amazon building amazon 4 1 Macbook object macbook 5 2 Sausages object sausages 6 3 Macbook object macbook 7 3 Tupperware object tupperware
What I'm attempting to do is query this table and get all items from level 1 (the buildings), but what I need to do is filter this return set by returning those that have children containing a certain value. The following query is what I have so far which returns Best Buy, Walmart, and Amazon
SELECT * FROM (
SELECT strval, parent_id, id
FROM stores
where LEVEL = 1
CONNECT BY PRIOR id = parent_id
START WITH parent_id = 0
)
What I would like to do is get a return where one of the descendants has a subtype of object and a subval of macbook, thus returning only Best Buy and Amazon from my query. I'm not really sure where to go from here.
Try reversing your CONNECT BY
condition and starting with (i.e., START WITH
) what you know:
SELECT DISTINCT strval, parent_id, id
FROM stores
where subtype = 'building'
CONNECT BY id = prior parent_id
START WITH subtype = 'object' and subval = 'macbook';
In the comments, you asked what if the starting values aren't at the same level?
In that case, I'm afraid you'll have to look at the whole tree for each building and then filter.
I added this row to your test data:
insert into stores values (8, 4, 'Year','edition','2015');
Then, this query gives the answer:
WITH whole_tree AS
(SELECT strval,
parent_id,
id,
CONNECT_BY_ROOT(strval) building,
SYS_CONNECT_BY_PATH (subtype || ':' || subval, ',') PATH
FROM stores
CONNECT BY PRIOR id = parent_id
START WITH subtype = 'building')
SELECT distinct building
FROM whole_tree
WHERE PATH LIKE '%object:macbook%edition:2015%';