Will Lovett Will Lovett - 2 months ago 12
SQL Question

How to retrieve all recursive children of parent row in Oracle SQL?

I've got a recursive query that's really stretching the limits of this Java monkey's SQL knowledge. Now that it's finally 1:30 in the AM, it's probably time to start looking for some help. This is one of the few times Google has failed me.

The table is as follows:

Parent_ID CHILD_ID QTY
25 26 1
25 27 2
26 28 1
26 29 1
26 30 2
27 31 1
27 32 1
27 33 2


I'm trying to get the following result, where the parent has every child listed below them. Note that the qty's cascade as well.

BASE PARENT_ID CHILD_ID QTY
25 25 26 1
25 25 27 2
25 26 28 1
25 26 29 1
25 26 30 1
25 27 31 2
25 27 32 2
25 27 33 4
26 26 28 1
26 26 29 1
26 26 30 2
27 27 31 1
27 27 32 1
27 27 33 2


I've tried several deviations of the following to no avail.

SELECT *
FROM MD_BOMS
START WITH PARENT_ID is not null
CONNECT BY PRIOR CHILD_ID = PARENT_ID
ORDER BY PARENT_ID, CHILD_ID


I'm using the Oracle database. Any suggestions, ideas, etc. would be greatly appreciated. This seems close, but I'm not sure if it's what I'm looking for: Retreive all Children and their Children, recursive SQL

Based on ( Retreive all Children and their Children, recursive SQL )I've also tried the following but receive an "illegal reference ofa query name in WITH clause" error:

with cte as (
select CHILD_ID, PARENT_ID, CHILD_ID as head
from MD_BOMS
where PARENT_ID is not null
union all
select ch.CHILD_ID, ch.PARENT_ID, p.head
from MD_BOMS ch
join cte pa
on pa.CHILD_ID = ch.PARENT_ID
)
select *
from cte

Answer

@AlexPoole answer is great, I just want to extend his answer with more intuitive variant of query for summing values along a path.
This variant based on recursive subquery factoring feature, introduced in Oracle 11g R2.

with recursion_view(base, parent_id, child_id, qty) as (
   -- first step, get rows to start with
   select 
     parent_id base, 
     parent_id, 
     child_id, 
     qty
  from 
    md_boms

  union all

  -- subsequent steps
  select
    -- retain base value from previous level
    previous_level.base,
    -- get information from current level
    current_level.parent_id,
    current_level.child_id,
    -- accumulate sum 
    (previous_level.qty + current_level.qty) as qty 
  from
    recursion_view previous_level,
    md_boms        current_level
  where
    current_level.parent_id = previous_level.child_id

)
select 
  base, parent_id, child_id, qty
from 
  recursion_view
order by 
  base, parent_id, child_id

SQLFiddle example (extended with one data row to demonstrate work with more then 2 levels)