복붙노트

[SQL] 자체 참조 테이블에 SQL 재귀 쿼리 (오라클)

SQL

자체 참조 테이블에 SQL 재귀 쿼리 (오라클)

나는이 샘플 데이터가 있다고 가정하자 :

| Name     | ID | PARENT_ID |
-----------------------------
| a1       | 1  | null      |
| b2       | 2  | null      |
| c3       | 3  | null      |
| a1.d4    | 4  | 1         |
| a1.e5    | 5  | 1         |
| a1.d4.f6 | 6  | 4         |
| a1.d4.g7 | 7  | 4         |
| a1.e5.h8 | 8  | 5         |
| a2.i9    | 9  | 2         |
| a2.i9.j10| 10 | 9         |

나는 예상되는 결과가 될 수 있도록 모든 기록, 계정 아이디 = 1에서 시작 선택하고 싶습니다 :

| Name     | ID | PARENT_NAME | PARENT_ID | 
-------------------------------------------
| a1       | 1  | null        | null      |
| a1.d4    | 4  | a1          | 1         |
| a1.e5    | 5  | a1          | 1         |
| a1.d4.f6 | 6  | a1.d4       | 4         |
| a1.d4.g7 | 7  | a1.d4       | 4         |
| a1.e5.h8 | 8  | a1.e5       | 5         |

저는 현재 재귀 선택을 할 수 있어요,하지만 나는 그래서 내가 PARENT_NAME을 반환하지 수, 부모의 기준에서 데이터를 액세스 할 수 없습니다. 내가 사용하는 코드는 (단순한 예에 적응)이다 :

SELECT id, parent_id, name
FROM tbl 
  START WITH id = 1 
  CONNECT BY PRIOR id = parent_id

무엇 SQL 내가 검색 위에서 언급에 사용되어야 하는가?

미래의 구직자에 대한 추가 핵심 단어 : SQL은 같은 테이블에 부모 키에 의해 표현 계층 적 데이터를 선택합니다

해결법

  1. ==============================

    1.사용하다:

    사용하다:

        SELECT t1.id, 
               t1.parent_id, 
               t1.name,
               t2.name AS parent_name,
               t2.id AS parent_id
          FROM tbl t1
     LEFT JOIN tbl t2 ON t2.id = t1.parent_id
    START WITH t1.id = 1 
    CONNECT BY PRIOR t1.id = t1.parent_id
    
  2. ==============================

    2.무엇 PRIOR 사용에 대한,

    무엇 PRIOR 사용에 대한,

    그래서 SELECT ID, PARENT_ID, PRIOR 이름    TBL FROM START WITH의 ID = 1 CONNECT BY PRIOR ID = parent_id`

  3. ==============================

    3.새로운 중첩 된 쿼리 구문을 사용하여

    새로운 중첩 된 쿼리 구문을 사용하여

    with q(name, id, parent_id, parent_name) as (
        select 
          t1.name, t1.id, 
          null as parent_id, null as parent_name 
        from t1
        where t1.id = 1
      union all
        select 
          t1.name, t1.id, 
          q.id as parent_id, q.name as parent_name 
        from t1, q
        where t1.parent_id = q.id
    )
    select * from q
    
  4. ==============================

    4.당신은이 작업을 수행 할 수 있습니까?

    당신은이 작업을 수행 할 수 있습니까?

    SELECT id, parent_id, name, 
     (select Name from tbl where id = t.parent_id) parent_name
    FROM tbl t start with id = 1 CONNECT BY PRIOR id = parent_id
    

    편집하다 (하지만 난 그 똑같이 수행합니다 생각) OMG의 하나를 기반으로 또 다른 옵션 :

    select 
               t1.id, 
               t1.parent_id, 
               t1.name,
               t2.name AS parent_name,
               t2.id AS parent_id
    from 
        (select id, parent_id, name
        from tbl
        start with id = 1 
        connect by prior id = parent_id) t1
        left join
        tbl t2 on t2.id = t1.parent_id
    
  5. ==============================

    5.그것은 성가신 측에 작은하지만합니다 (추가 가입없이) 나는이 일 전망이다. 이렇게하면, 해당 필드에 표시하지 않습니다 문자를 선택할 수있는 분리 역할을하는 것으로 가정합니다.

    그것은 성가신 측에 작은하지만합니다 (추가 가입없이) 나는이 일 전망이다. 이렇게하면, 해당 필드에 표시하지 않습니다 문자를 선택할 수있는 분리 역할을하는 것으로 가정합니다.

    당신은 선택을 중첩하지 않고 그것을 할 수 있습니다,하지만 난 SYS_CONNECT_BY_PATH 네 개의 참조를 갖는이 조금 청소기를 찾을 수 있습니다.

    select id, 
           parent_id, 
           case 
             when lvl <> 1 
             then substr(name_path,
                         instr(name_path,'|',1,lvl-1)+1,
                         instr(name_path,'|',1,lvl)
                          -instr(name_path,'|',1,lvl-1)-1) 
             end as name 
    from (
      SELECT id, parent_id, sys_connect_by_path(name,'|') as name_path, level as lvl
      FROM tbl 
      START WITH id = 1 
      CONNECT BY PRIOR id = parent_id)
    
  6. from https://stackoverflow.com/questions/2319284/sql-recursive-query-on-self-referencing-table-oracle by cc-by-sa and MIT license