Определение порядка сортировки дочерних элементов в запросе иерархии
Я хотел бы знать SQL-запрос Oracle, который упорядочивает дочерние элементы в запросе иерархии по столбцу sequence_within_parent.
пример набора данных и запроса:
create table tasks (task_id number
,parent_id number
,sequence_within_parent number
,task varchar2(30)
);
insert into tasks values ( 1, NULL, 0, 'Task 1');
insert into tasks values ( 2, 1, 1, 'Task 1.1');
insert into tasks values ( 3, 1, 2, 'Task 1.2');
insert into tasks values ( 4, 2, 2, 'Task 1.1.2');
insert into tasks values ( 5, 3, 1, 'Task 1.2.1');
insert into tasks values ( 6, 2, 1, 'Task 1.1.1');
insert into tasks values ( 7, 3, 4, 'Task 1.2.4');
insert into tasks values ( 8, 3, 2, 'Task 1.2.2');
insert into tasks values ( 9, 3, 3, 'Task 1.2.3');
insert into tasks values (10 , 2, 3, 'Task 1.1.3');
column task format a30
select task_id
,sequence_within_parent
,lpad(' ', 2 * (level - 1), ' ') || task task
from tasks
connect by parent_id = prior task_id
start with task_id = 1
/
этот запрос возвращает следующее:
TASK_ID SEQUENCE_WITHIN_PARENT TASK
---------- ---------------------- ---------------
1 0 Task 1
2 1 Task 1.1
4 2 Task 1.1.2
6 1 Task 1.1.1
10 3 Task 1.1.3
3 2 Task 1.2
5 1 Task 1.2.1
7 4 Task 1.2.4
8 2 Task 1.2.2
9 3 Task 1.2.3
предпочтительный выход, где дети находятся в правильном порядке:
TASK_ID SEQUENCE_WITHIN_PARENT TASK
---------- ---------------------- ---------------
1 0 Task 1
2 1 Task 1.1
6 1 Task 1.1.1
4 2 Task 1.1.2
10 3 Task 1.1.3
3 2 Task 1.2
5 1 Task 1.2.1
8 2 Task 1.2.2
9 3 Task 1.2.3
7 4 Task 1.2.4
2 ответов
пункт для добавления в запрос "братья и сестры заказа SEQUENCE_WITHIN_PARENT".
в иерархии все дочерние узлы или дочерние узлы называются братьями и сестрами.
полный запрос для набора данных:
select rownum
,task_id
,sequence_within_parent
,lpad(' ', 2 * (level - 1), ' ') || task task
from tasks
connect by parent_id = prior task_id
start with task_id = 1
order siblings by sequence_within_parent
/
SQL Server имеет тип hierarchyID, который очень хорошо обрабатывает это. Для всех других СУБД я обычно использую эмуляцию конката строк, как показано ниже.
select task_id
,sequence_within_parent
,lpad(' ', 2 * (level - 1), ' ') || task task
,SYS_CONNECT_BY_PATH(
to_char(parent_id, 'FM000000000')
||
to_char(sequence_within_parent, 'FM000000000')
,'/') hier
from tasks
connect by parent_id = prior task_id
start with task_id = 1
order by hier;