2016-12-30 5 views
1

H2 데이터베이스를 사용하려고합니다. Derby Database에는 많은 기능이 있습니다. 하나는 Recursion입니다. 그러나 유비쿼터스 scott/tiger의 EMP 테이블을 시험해 보았을 때 그 결과는 기대만큼 좋지 않았습니다. 봐 주시기 바랍니다 :H2 데이터베이스 재귀 쿼리 결과가 잘못되었습니다.

with e1(empno, ename, mgr, job, hiredate, l) as ( 
select empno, ename, mgr, job, hiredate, 0 
from emp 
where mgr is null 
union all 
select e2.empno, e2.ename, e2.mgr, e2.job, e2.hiredate, l+1 
from emp e2, e1 
where e2.mgr = e1.empno) 
select * from e1; 

결과를 :

EMPNO ENAME MGR JOB HIREDATE L 
7839 KING null PRESIDENT 1981-11-17 0 
7566 JONES 7839 MANAGER 1981-04-02 1 
7698 BLAKE 7839 MANAGER 1981-05-01 1 
7782 CLARK 7839 MANAGER 1981-06-09 1 
7499 ALLEN 7698 SALESMAN 1981-02-20 2 
7521 WARD 7698 SALESMAN 1981-02-22 2 
7654 MARTIN 7698 SALESMAN 1981-09-28 2 
7788 SCOTT 7566 ANALYST 1987-07-13 2 
7844 TURNER 7698 SALESMAN 1981-09-08 2 
7900 JAMES 7698 CLERK 1981-12-03 2 
7902 FORD 7566 ANALYST 1981-12-03 2 
7934 MILLER 7782 CLERK 1982-01-23 2 
7369 SMITH 7902 CLERK 1980-12-17 3 
7876 ADAMS 7788 CLERK 1987-07-13 3 
(14 rows, 0 ms) 

모든 관리자는 다르게 결과 등 다음 내가 원하는 을 점원을 조립하고있다. 나는 포스트 그레스에서 다음을 수행 한 동일한 쿼리

:

with recursive emp_tree(empno, ename, deptno, job, sal, mgr, l, tree) as (
select empno, 
     ename, 
     deptno, 
     job, 
     sal, 
     mgr, 
     0 as l, 
     Array[empno] || '{}' 
from emp 
where mgr is null 
union all 
select e2.empno, 
     e2.ename, 
     e2.deptno, 
     e2.job, 
     e2.sal, 
     e2.mgr, 
     emp_tree.l + 1, 
     Array_append(tree, e2.empno) 
from emp e2, 
     emp_tree 
where e2.mgr = emp_tree.empno) 
select * from emp_tree 
order by tree 

그리고 그 결과는 매우 완벽하다 :

"empno";"ename";"deptno";"job";"sal";"mgr";"l";"tree" 
7839;"KING";10;"PRESIDENT";5000.00;;0;"{7839}" 
7566;"JONES";20;"MANAGER";2975.00;7839;1;"{7839,7566}" 
7788;"SCOTT";20;"ANALYST";3000.00;7566;2;"{7839,7566,7788}" 
7876;"ADAMS";20;"CLERK";1100.00;7788;3;"{7839,7566,7788,7876}" 
7902;"FORD";20;"ANALYST";3000.00;7566;2;"{7839,7566,7902}" 
7369;"SMITH";20;"CLERK";800.00;7902;3;"{7839,7566,7902,7369}" 
7698;"BLAKE";30;"MANAGER";2850.00;7839;1;"{7839,7698}" 
7499;"ALLEN";30;"SALESMAN";1600.00;7698;2;"{7839,7698,7499}" 
7521;"WARD";30;"SALESMAN";1250.00;7698;2;"{7839,7698,7521}" 
7654;"MARTIN";30;"SALESMAN";1250.00;7698;2;"{7839,7698,7654}" 
7844;"TURNER";30;"SALESMAN";1500.00;7698;2;"{7839,7698,7844}" 
7900;"JAMES";30;"CLERK";950.00;7698;2;"{7839,7698,7900}" 
7782;"CLARK";10;"MANAGER";2450.00;7839;1;"{7839,7782}" 
7934;"MILLER";10;"CLERK";1300.00;7782;2;"{7839,7782,7934}" 

계층 적 쿼리에 내가 EMPNO에 결과를 주문할 수 있습니다 또는 입사 날짜가 SMITH (서기관)가 KING (회장) 전에 합류했기 때문입니다. 그래서 SMITH의 empno는 KING의 empno 앞에 있습니다.

H2에서 동일한 작업을 수행하려면 나에게 제안하십시오. 당신이 어떤 정렬 순서를 지정하지 않은, 그래서 데이터베이스가 원하는 임의의 순서를 자유롭게 선택할 수 -

감사

BB23850

답변

0

당신이 H2 얻을 결과에 관해서는 "올바른"입니다.

당신은 문자열 연결하여 H2에서 포스트 그레스에서 사용하는 배열을 시뮬레이션 할 수 있습니다 :

with e1 (empno, ename, mgr, job, hiredate, path, lvl) as 
( 
    select empno, ename, mgr, job, hiredate, '/'||lpad(empno, 6, '0'), 0 
    from emp 
    where mgr is null 
    union all 
    select child.empno, child.ename, child.mgr, child.job, child.hiredate, 
     parent.path||'/'||lpad(child.empno, 6, '0'), 
     parent.lvl + 1 
    from emp child 
    join e1 parent on child.mgr = parent.empno 
) 
select * 
from e1 
order by path; 

LPAD() 마지막 순서로 문자열에서 수행되고있다 '10''2' 전에 분류 될 수 있기 때문에 필요를 . 숫자를 0으로 채우면 문자열 비교를 통해 문제가 해결됩니다.

+0

감사합니다. 이것은 나를 위해 작동합니다. – BB23850