2

제품의 트리 구조를 수용하기 위해 생성 된 PRODUCTS 테이블을 처리해야합니다. 하나의 제품이 다른 여러 제품을 포함 할 수있는 상황을 처리하기 위해 수행됩니다 (예 : 하나의 패키지 제품이 다른 여러 위치를 보유하고 있음). 따라서 OrderDetails를 사용하는 함수를 만들고 있는데, 모든 제품을 반복하고 나열된 각 제품의 하위 제품을 나열해야합니다. 나는 알 수없는 깊이의 나무를 통해 반복해야만하는 문제에 직면하고있다. 제발, 어떻게 할 생각인지 말해줘.SQL 트리에서 모든 형제를 얻으십시오

아래 표에 나와있는 기능과 함께이 기능을 구현했습니다. 그러나 그 해법에서리스트의 깊이는 1로 제한되어 있고, 내가하고 싶은 것은 트리의 모든 깊이를 가져 오는 것입니다. 여기

코드입니다 : CTE이 usign를 완료

CREATE OR REPLACE FUNCTION foo()RETURNS text AS 
$body$ 
DECLARE _row RECORD; 
     _result text := ''; 
     _child_row RECORD; 
     _count integer := -1; 
     _marker integer := 1; 
BEGIN 
    FOR _row IN SELECT * FROM tree_products 
    LOOP 
     _result := _result || _marker || ' ' || _row.name; 
     _count := (SELECT count(product_id) FROM tree_products WHERE parent_id = _row.product_id); 
     IF _count > 0 THEN 
      FOR _child_row IN SELECT * FROM tree_products WHERE parent_id = _row.product_id 
      LOOP 
       _result := _result || ' ' || _child_row.name; 
      END LOOP; 
     END IF; 
     _marker := _marker =1;  
    END LOOP; 
END; 
$body$ 
    LANGUAGE plpgsql 

UPD하지만 groupiing 문제가 발생했습니다 :

나는 제품들이 respectiveparents하에 형제하려는
CREATE OR REPLACE FUNCTION public.__foo (
) 
RETURNS SETOF refcursor AS 
$body$ 
DECLARE _returnvalue refcursor; 
     _q text; 
BEGIN 
_q :=' 
     WITH RECURSIVE r_p (product_id, name, parent_id) AS -- 1 
    (SELECT t_p.product_id, t_p.name , t_p.parent_id -- 2 
    FROM tree_products t_p 
    WHERE t_p.product_id = 1 
    UNION ALL 
    SELECT t_c.product_id, t_c.name, t_c.parent_id -- 3 
    FROM r_p t_p, tree_products t_c 
    WHERE t_c.parent_id = t_p.product_id) 
SELECT product_id, name, parent_id      -- 4 
FROM r_p;'; 
OPEN _returnvalue FOR EXECUTE (_q); 
RETURN NEXT _returnvalue; 
END 
$body$ 
LANGUAGE 'plpgsql' 
VOLATILE 
CALLED ON NULL INPUT 
SECURITY INVOKER 
COST 100 ROWS 1000; 

, 궁금 방법 그룹화 문구 작성 ...

UPD 죄송합니다. tree_products의 정의는 다음과 같습니다.

,
CREATE TABLE public.tree_products (
    product_id INTEGER DEFAULT nextval('ree_products_product_id_seq'::regclass) NOT NULL, 
    name VARCHAR, 
    parent_id INTEGER, 
    CONSTRAINT ree_products_pkey PRIMARY KEY(product_id) 
) 
WITH (oids = false); 

UPD : 샘플 출력 :

product_id | name   | parent_id 
--------------------------------------- 
1   | promo   | NULL 
3   | fork   | 1 
4   | spoon   | 1 
6   | can   | 1 
10   | big can  | 3 
11   | small can  | 4 
12   | large spoon | 6 
13   | mega fork  | 3 
14   | super duper | 6 

DESIRED OUTPUT: 

product_id | name   | parent_id 
--------------------------------------- 
1   | promo   | NULL 
3   | fork   | 1 
10   | big can  | 3 
13   | mega fork  | 3 
4   | spoon   | 1 
11   | small can  | 4 
6   | can   | 1 
12   | large spoon | 6 
14   | super duper | 6 

So, the fetched table has structure of the real tree, like the follwing: 
- promo 
    - fork 
    - big can 
    - mega fork 
    - spoon 
    - small can 
    - can 
    - large can 
    - super duper 
+0

[트리 뷰 OF DATA FOR GET의 LINK] [1] [1] : http://stackoverflow.com/questions/21183886/get-hierarchical-data-in-mysql/ 21201379 # 21201379 유용 할 수도 있습니다. –

+1

'WITH RECURSIVE'검색어로 재귀 적 CTE와 같은 일을 수행하는 것이 일반적으로 더 쉽습니다. http://www.postgresql.org/docs/current/static/queries-with.html을 참조하십시오. 보다 자세한 도움이 필요하면'products' 테이블의 정의와 샘플 데이터를 게시하는 것이 좋습니다. –

+0

@CraigRinger [sqlfiddle] (http://sqlfiddle.com)을 사용하여 데이터베이스 쿼리를 탐색하는 데 유용하다는 사실을 발견했습니다. – hd1

답변

2

This SQLFiddle 배열에 부모 행 번호의 목록을 유지, 나무 위에서 아래를 통과, 본질적으로 "부모 행 위치 목록".

그런 다음 결과를 상위 목록별로 정렬합니다.

WITH RECURSIVE tree(product_id, name, parentlist) AS (
    SELECT product_id, name, ARRAY[ row_number() OVER (ORDER BY product_id) ] 
    FROM tree_products 
    WHERE parent_id IS NULL 
    UNION 
    SELECT tp.product_id, tp.name, array_append(parentlist, row_number() OVER (ORDER BY tp.product_id)) 
    FROM tree_products tp 
    INNER JOIN tree t 
    ON (tp.parent_id = t.product_id) 
) 
SELECT * 
FROM tree 
ORDER BY parentlist;