codememo

Oracle SQL에서 상위 행의 모든 재귀 자식을 검색하는 방법은 무엇입니까?

tipmemo 2023. 7. 17. 21:08
반응형

Oracle SQL에서 상위 행의 모든 재귀 자식을 검색하는 방법은 무엇입니까?

이 자바원숭이의 SQL 지식의 한계를 확장시키는 재귀적인 질문이 있습니다.이제 드디어 새벽 1시 30분이 되었으니, 아마도 도움을 청하기 시작할 시간입니다.이것은 구글이 저를 실망시킨 몇 안 되는 경우 중 하나입니다.

표는 다음과 같습니다.

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

저는 다음과 같은 결과를 얻으려고 노력하고 있습니다. 부모는 아래에 있는 모든 아이들을 가지고 있습니다.QTY도 캐스케이드입니다.

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

저는 다음의 몇 가지 편차를 시도했지만 소용이 없었습니다.

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

저는 오라클 데이터베이스를 사용하고 있습니다.어떤 제안이나 아이디어 등도 주시면 감사하겠습니다.이것이 가까운 것처럼 보이지만 제가 찾고 있는 것이 맞는지 확실하지 않습니다: 모든 자식 자식 검색, 재귀 SQL

(Retrieve all Children and their Children, recursive SQL)에 기반하여 다음도 시도했지만 "WITH 절의 쿼리 이름에 대한 잘못된 참조" 오류가 발생했습니다.

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

근접했습니다.

select connect_by_root parent_id base, parent_id, child_id, qty
from md_boms
connect by prior child_id = parent_id
order by base, parent_id, child_id;

          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          2 
            25         27         31          1 
            25         27         32          1 
            25         27         33          2 
            26         26         28          1 
            26         26         29          1 
            26         26         30          2 
            27         27         31          1 
            27         27         32          1 
            27         27         33          2 

     14 rows selected 

연산자는 당신에게 베이스를 제공합니다.parent_id.

SQL Fiddle.

당신이 어떻게 계산하고 있는지 잘 모르겠습니다.qty아이에게 가는 길의 총합을 원하는 것 같은데, 당신이 보여준 것과 일치하지 않습니다.그 시작점으로, 이 답변에서 매우 많이 차용하면 다음과 같은 것을 시도할 수 있습니다.

with hierarchy as (
  select connect_by_root parent_id base, parent_id, child_id, qty,
    sys_connect_by_path(child_id, '/') as path
  from md_boms
  connect by prior child_id = parent_id
)
select h.base, h.parent_id, h.child_id, sum(e.qty)
from hierarchy h
join hierarchy e on h.path like e.path ||'%'
group by h.base, h.parent_id, h.child_id
order by h.base, h.parent_id, h.child_id;

     BASE  PARENT_ID   CHILD_ID SUM(E.QTY)
---------- ---------- ---------- ----------
        25         25         26          1 
        25         25         27          2 
        25         26         28          2 
        25         26         29          2 
        25         26         30          3 
        25         27         31          3 
        25         27         32          3 
        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 

 14 rows selected 

@AlexPool 답변은 훌륭합니다. 경로를 따라 값을 합산하기 위한 보다 직관적인 쿼리 변형으로 답변을 확장하고 싶습니다.
재귀적 하위 쿼리 팩터링 기능을 기반으로 한 변형으로,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

SQL 중간 예제(두 개 이상의 수준을 갖는 작업을 시연하기 위해 하나의 데이터 행으로 확장)

언급URL : https://stackoverflow.com/questions/17358109/how-to-retrieve-all-recursive-children-of-parent-row-in-oracle-sql

반응형