2016-12-30 3 views
1

Я пробую базу данных H2. Он имеет много возможностей по сравнению с Derby Database, так как один из них - Recursion. Но когда я попробовал повсеместную таблицу EMP scott/tiger, результаты не совсем ожидаются. Пожалуйста, обратите внимание: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) 

Все МЕНЕДЖЕРЫ ставятся вместе, а затем клерки и т.д. я хочу привести быть разными.

Для того же запроса я сделал следующее Postgres:

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 или дата присоединения, потому что к ним присоединился СМИТ (Клерк) до Кинга (президент). Итак, empno SMITH находится перед empno KING.

Пожалуйста, предложите мне работу, чтобы сделать то же самое в H2.

спасибо и касается

BB23850

ответ

0

Результат вы получите в Н2 «правильно» - вы не указали порядок сортировки, поэтому база данных волен выбрать любой заказ он хочет.

Вы можете имитировать массив, который вы используете в Postgres в 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

Спасибо. Это работает для меня. – BB23850

Смежные вопросы