Abh*_*988 0 sql oracle connect-by hierarchical-data
我有一个表,其中定义了父/子关系,但无法通过层次结构级别进行排序。
For example consider this:
empid managerid name
js hd George
hd ab Mary
hs js Tom
ab xx John
Run Code Online (Sandbox Code Playgroud)
由于我无法使用 ORDER SIBLINGS BY 以分层方式排序,我将如何能够以分层方式对其进行排序,如下所示?
empid managerid name
ab xx John
hd ab Mary
js hd George
hs js Tom
Run Code Online (Sandbox Code Playgroud)
如果向我们展示您迄今为止尝试过的查询将会很有帮助。听起来好像有什么地方有误会。
对于您非常小的样本数据Eng. Samer T,答案是正确的。你不需要order by条款。Oracle 保证查询中的行将按分层顺序返回connect by。有关分层查询的 Oracle 文档:
- Oracle 按图 9-1 所示的顺序返回行。在图中,孩子出现在父母的下方。
无法保证同一层次结构级别(同级)中的行将如何排序。但由于您的示例数据每个级别只有一个子级,因此这实际上并不重要。
然而,让我们考虑一个具有更多数据的示例,以便我们有兄弟姐妹。
create table Employee (
empid varchar2(50) not null,
managerid varchar2(50) not null,
name varchar2(50) not null
)
/
insert into Employee (empid, managerid, name) values ('js', 'hd', 'George');
insert into Employee (empid, managerid, name) values ('hd', 'ab', 'Mary');
insert into Employee (empid, managerid, name) values ('hs', 'js', 'Tom');
insert into Employee (empid, managerid, name) values ('ww', 'js', 'Waldo');
insert into Employee (empid, managerid, name) values ('ab', 'xx', 'John');
insert into Employee (empid, managerid, name) values ('ab2', 'xx', 'Other manager');
insert into Employee (empid, managerid, name) values ('st', 'ab2', 'Stan');
insert into Employee (empid, managerid, name) values ('lee', 'ab2', 'Lee');
alter table employee
add constraint employee_pk
primary key (empid)
/
Run Code Online (Sandbox Code Playgroud)
如果我随后运行以下不带子句的connect by查询:order by
select t.*, level
from employee t
start with t.managerid = 'xx'
connect by prior t.empid = t.managerid
Run Code Online (Sandbox Code Playgroud)
我得到(SqlFiddle):
empid managerid name level
----- --------- ---- -----
ab xx John 1
hd ab Mary 2
js hd George 3
hs js Tom 4
ww js Waldo 4
ab2 xx Other manager 1
lee ab2 Lee 2
st ab2 Stan 2
Run Code Online (Sandbox Code Playgroud)
请注意如何尊重层次结构,这是有保证的。然而,对于兄弟姐妹来说,顺序并不能保证。例如,不保证始终John会列在 之前、会列在 之前或会列在之前Other managerTomWaldoLeeStan。
如果您想保证兄弟姐妹内的排序,但又不破坏层次结构的顺序,那么这正是order siblings by子句的用途。
所以我不知道你为什么说:
我不能用于
ORDER SIBLINGS BY以分层方式排序
因为,Oracle 关于分层查询的文档几乎是相反的:
在分层查询中,请勿指定 或
ORDER BY,GROUP BY因为它们将覆盖结果的分层顺序CONNECT BY。如果要对同一父级的同级行进行排序,请使用该ORDER SIBLINGS BY子句。
请注意它如何特别建议使用 来order siblings by对兄弟姐妹进行排序,而无需破坏结果的层次顺序。
假设我希望我的结果按层次结构排序,但让兄弟姐妹按名称降序按字母顺序排序。然后我可以将之前的查询调整为:
select t.*, level
from employee t
start with t.managerid = 'xx'
connect by prior t.empid = t.managerid
order siblings by name desc
Run Code Online (Sandbox Code Playgroud)
我的结果变成(SqlFiddle):
empid managerid name level
----- --------- ---- -----
ab2 xx Other manager 1
st ab2 Stan 2
lee ab2 Lee 2
ab xx John 1
hd ab Mary 2
js hd George 3
ww js Waldo 4
hs js Tom 4
Run Code Online (Sandbox Code Playgroud)
请注意,等级制度仍然受到尊重。但是兄弟姐妹John和Other manager被重新排序,因此Other manager整个结果树都列在 之前John。而且,Waldo现在总会出现在以前Tom,并且Stan总会出现在以前Lee。