복붙노트

[SQL] 그것은 재귀 SQL 쿼리를 만들 수 있습니까?

SQL

그것은 재귀 SQL 쿼리를 만들 수 있습니까?

나는이 유사한 테이블이 있습니다 :

CREATE TABLE example (
  id integer primary key,
  name char(200),
  parentid integer,
  value integer);

저는 트리 구조로 데이터를 정렬합니다 parentid 필드를 사용할 수 있습니다.

지금 여기에 내가 해결할 수없는 비트입니다. parentid을 감안할 때, 그 parentid 아래의 모든 값 필드를 추가하고 트리의 분기를 재귀하는 SQL 문을 작성할 수 있습니다?

업데이트 : PostgreSQL을이 멋진 MS-SQL의 기능이 나에게 사용할 수 없습니다 이렇게 사용하고 있습니다. 어떤 경우에는,이는 일반적인 SQL 질문으로 처리하고 싶습니다.

BTW, 나는 매우 질문을 15 분 이내에 6 개 답변을 가지고 감동! 스택 오버플로 이동!

해결법

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

    1.당신은 PostgreSQL을에 필요한 일을 할 수있는 몇 가지 방법이 있습니다.

    당신은 PostgreSQL을에 필요한 일을 할 수있는 몇 가지 방법이 있습니다.

    이 같은:

    create or replace function example_subtree (integer)
    returns setof example as
    'declare results record;
             child record;
     begin
      select into results * from example where parent_id = $1;
      if found then
        return next results;
        for child in select id from example
                      where parent_id = $1
          loop
            for temp in select * from example_subtree(child.id)
            loop
              return next temp;
            end loop;
          end loop;
      end if;
      return null;
    end;' language 'plpgsql';
    
    select sum(value) as value_sum
      from example_subtree(1234);
    
  2. ==============================

    2.여기에 공통 테이블 식을 사용하는 예제 스크립트입니다 :

    여기에 공통 테이블 식을 사용하는 예제 스크립트입니다 :

    with recursive sumthis(id, val) as (
        select id, value
        from example
        where id = :selectedid
        union all
        select C.id, C.value
        from sumthis P
        inner join example C on P.id = C.parentid
    )
    select sum(val) from sumthis
    

    이 스크립트는 위의 열 ID와 발을 가진 '가상'테이블이라고 sumthis을 만듭니다. 그것은 노동 조합 모두 합병이 선택의 결과로 정의된다.

    (: selectedid ID =) 첫 번째 선택은 루트를 가져옵니다.

    반환에 아무것도 없을 때까지 두 번째 선택은 반복적으로 이전 결과의 아이들을 따른다.

    최종 결과는 다음 일반 테이블처럼 처리 될 수있다. 이 경우, 발 열은 합산된다.

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

    3.버전 8.4 이후, PostgreSQL은 구문으로 SQL 표준을 사용하여 공통 테이블 표현식에 대한 재귀 쿼리 지원을하고 있습니다.

    버전 8.4 이후, PostgreSQL은 구문으로 SQL 표준을 사용하여 공통 테이블 표현식에 대한 재귀 쿼리 지원을하고 있습니다.

  4. ==============================

    4.당신이 어떤 ANSI SQL-92 RDBMS에서 작동 휴대용 솔루션을 원하는 경우에, 당신은 당신의 테이블에 새 열을 추가해야합니다.

    당신이 어떤 ANSI SQL-92 RDBMS에서 작동 휴대용 솔루션을 원하는 경우에, 당신은 당신의 테이블에 새 열을 추가해야합니다.

    조 셀코는 중첩 된 세트의 원래 저자가 SQL에서 계층 구조를 저장하는 방법입니다. 당신은 구글 "중첩 된 세트"계층은 더 많은 배경에 대한 이해 할 수 있습니다.

    아니면 그냥 leftid에 parentid의 이름을 변경하고 rightid를 추가 할 수 있습니다.

    여기에 내가 더 조 셀코 해요 없기 때문에 비참하게 미달 할 중첩 된 세트, 요약 내 시도입니다 : SQL은 집합 기반 언어이며, 인접 모델 (부모 ID를 저장)은 계층 구조의 집합 기반의 표현이 아닙니다. 따라서 인접성 스키마를 조회 할 순수한 세트 기반 방법이 없습니다.

    그러나, 주요 플랫폼의 대부분이 정확한 문제를 해결하기 위해 최근 몇 년 동안 확장을 도입했습니다. 그래서 포스트 그레스 특정 솔루션을 가진 사람의 응답이 사용하는 경우 모든 수단에 의해.

  5. ==============================

    5.SQL에서 재귀 쿼리를 만드는 표준 방법은 CTE 재귀입니다. PostgreSQL은 8.4 이후를 지원합니다.

    SQL에서 재귀 쿼리를 만드는 표준 방법은 CTE 재귀입니다. PostgreSQL은 8.4 이후를 지원합니다.

    이전 버전에서는 재귀 집합을 반환하는 함수를 작성할 수 있습니다 :

    CREATE FUNCTION fn_hierarchy (parent INT)
    RETURNS SETOF example
    AS
    $$
            SELECT  example
            FROM    example
            WHERE   id = $1
            UNION ALL
            SELECT  fn_hierarchy(id)
            FROM    example
            WHERE   parentid = $1
    $$
    LANGUAGE 'sql';
    
    SELECT  *
    FROM    fn_hierarchy(1)
    

    이 문서를 참조하십시오 :

  6. ==============================

    6.당신은 SQL 서버 2005를 사용하는 경우, 일반 테이블 식을 사용하여이 작업을 수행 할 수있는 정말 멋진 방법이있다.

    당신은 SQL 서버 2005를 사용하는 경우, 일반 테이블 식을 사용하여이 작업을 수행 할 수있는 정말 멋진 방법이있다.

    그것은 임시 테이블을 만드는 밖으로 gruntwork의 모든 소요되며, basicly 당신이 함께하고 UNION 단지로 모든 것을 할 수 있습니다.

    여기에 좋은 튜토리얼입니다 :

    http://searchwindevelopment.techtarget.com/tip/0,289483,sid8_gci1278207,00.html

  7. ==============================

    7.공통 테이블 식을 사용합니다.

    공통 테이블 식을 사용합니다.

    여기에 공통 테이블 표현식없이 SqlTeam에 의해 재귀에 대한 기사입니다.

  8. ==============================

    8.다음 코드 컴파일과의 테스트 OK.

    다음 코드 컴파일과의 테스트 OK.

    create or replace function subtree (bigint)
    returns setof example as $$
    declare
        results record;
        entry   record;
        recs    record;
    begin
        select into results * from example where parent = $1;
        if found then
            for entry in select child from example where parent = $1 and child  parent loop
                for recs in select * from subtree(entry.child) loop
                    return next recs;
                end loop;
            end loop;
        end if;
        return next results;
    end;
    $$ language 'plpgsql';
    

    노드가 자신을 가리 키 때문에 상태 "아이 <> 부모는"내 경우에 필요하다.

    재미를 :)

  9. ==============================

    9.오라클은 "START WITH"와 "CONNECT BY"가

    오라클은 "START WITH"와 "CONNECT BY"가

    select 
        lpad(' ',2*(level-1)) || to_char(child) s
    
    from 
        test_connect_by 
    
    start with parent is null
    connect by prior child = parent;
    

    http://www.adp-gmbh.ch/ora/sql/connect_by.html

  10. ==============================

    10.질문이 아주 잘 대답하고있다 따로 있지만, 간단한, 그것은 주목해야 하듯이 우리가 같이이 취급하는 경우 :

    질문이 아주 잘 대답하고있다 따로 있지만, 간단한, 그것은 주목해야 하듯이 우리가 같이이 취급하는 경우 :

    (I 더 RDBMS를 완전히 표준을 구현하지 믿고 있지만) SQL'99가 WITH RECURSIVE 문을 통해 사양에 선형 재귀를 허용하는 다음 SQL 구현은 상당히 솔직하다. 이론적 관점에서 그래서 우리는 지금이 작업을 수행 할 수 있습니다.

  11. ==============================

    11.나는 이런 식으로 해결했습니다 있도록 예제 아무도 나를 위해 확인을 일했다 :

    나는 이런 식으로 해결했습니다 있도록 예제 아무도 나를 위해 확인을 일했다 :

    declare
        results record;
        entry   record;
        recs    record;
    begin
        for results in select * from project where pid = $1 loop
            return next results;
            for recs in select * from project_subtree(results.id) loop
                return next recs;
            end loop;
        end loop;
        return;
    end;
    
  12. ==============================

    12.이 SQL 서버는? 당신은 SQL 저장 프로 시저를 쓸 수 없습니다 것을 통해 루프와 노동 조합 함께 결과?

    이 SQL 서버는? 당신은 SQL 저장 프로 시저를 쓸 수 없습니다 것을 통해 루프와 노동 조합 함께 결과?

    이 생각을하고의 SQL-유일한 방법이 있다면 나 또한 관심이 있어요. 내 지리 데이터베이스 클래스에서 기억 비트에서이 있어야합니다.

  13. ==============================

    13.나는 HIERARCHYID와 SQL 2008에서 쉽게 생각

    나는 HIERARCHYID와 SQL 2008에서 쉽게 생각

  14. ==============================

    14.당신이 임의의 그래프뿐만 아니라 계층 구조를 저장해야하는 경우, 당신은 옆으로 포스트 그레스를 밀어 및 인 AllegroGraph와 같은 그래프 데이터베이스를 시도해 볼 수도 있습니다 :

    당신이 임의의 그래프뿐만 아니라 계층 구조를 저장해야하는 경우, 당신은 옆으로 포스트 그레스를 밀어 및 인 AllegroGraph와 같은 그래프 데이터베이스를 시도해 볼 수도 있습니다 :

    그래프에 의하면 모든 트리플 (소스 노드, 에지, 대상 노드)로 저장하고, 당신에게 그래프 구조를 조작 언어 같은 SQL을 사용하여 쿼리에 대한 일급 지원을 제공한다.

    그것은 최대 절전 모드 또는 장고 ORM 같은 것을 잘 통합 있지만 (중첩 된 세트 모델을 제공처럼뿐만 아니라 계층 구조)는 그래프 구조에 대한 심각한 경우를 확인하지 않습니다.

    또한 오라클은 마침내 자신들의 최신 제품을 실제 그래프에 대한 지원이 추가되었습니다 생각하지만, 나는 너무 오래, 많은 문제는이 모델에서 이익을 얻을 수 걸렸다 깜짝 놀라게하고있다.

  15. from https://stackoverflow.com/questions/53108/is-it-possible-to-make-a-recursive-sql-query by cc-by-sa and MIT license