0

我有一个表,其中定义了父/子关系,但无法通过层次结构进行排序。

For example consider this:
   empid  managerid   name 
    js       hd      George
    hd       ab       Mary
    hs       js       Tom
    ab       xx       John

由于我不能使用 ORDER SIBLINGS BY 以分层方式进行排序,我将如何以如下的分层方式对其进行排序?

     empid managerid  name 
     ab       xx       John
     hd       ab       Mary
     js       hd      George
     hs       js       Tom
4

3 回答 3

6

向我们展示您迄今为止尝试过的查询会很有帮助。好像哪里有误会。

对于您非常小的样本数据Eng. Samer T的答案是正确的。你不需要一个order by子句。connect byOracle 保证在查询中将按层次顺序返回行。关于分层查询的 Oracle 文档

  1. 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)
/

如果我在没有子句的情况下运行以下connect by查询:order by

select t.*, level
from employee t
start with t.managerid = 'xx'
connect by prior t.empid = t.managerid

我得到(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

请注意如何尊重层次结构,这是有保证的。但是,对于兄弟姐妹,顺序不能保证。例如,不能保证John总是在之前列出,或者会在之前列出Other manager,或者会在之前列出。TomWaldoLeeStan

如果您想保证兄弟姐妹之间的顺序,但又不破坏层次结构的顺序,这正是该order siblings by子句的用途。

所以我不知道你为什么说:

我不能ORDER SIBLINGS BY用于以分层方式排序

因为,关于分层查询的 Oracle 文档几乎是相反的:

在分层查询中,不要指定ORDER BYGROUP 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

我的结果变成(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

请注意层次结构仍然受到尊重。但是兄弟姐妹JohnOther manager被重新排序,以便Other manager' 的整个结果树列在John' 之前。此外,Waldo将现在总是出现在之前Tom,并且Stan总是出现在之前Lee

于 2015-08-25T01:39:46.993 回答
0

默认的“connect by”子句将返回结果。

只是从头开始,我认为“xx”表示没有经理。

select t.*, t.rowid from emp_table t
start with managerid = 'xx'
connect by prior empid = managerid
于 2015-08-24T22:32:21.513 回答
0

谢谢大家.... ORDER BY level 给出了我想要的结果。我不知道 Oracle 中已经定义了级别。

于 2015-08-25T06:14:29.790 回答