Sql Oracle中的分层查询-失控?
我在Oracle10SQL中有一个分层查询,它过去是有效的。然而,我删除了它所基于的物化视图,现在我无法正确地将其显示出来,甚至完全忽略了该视图 原始查询如下所示:Sql Oracle中的分层查询-失控?,sql,oracle,plsql,hierarchical-data,Sql,Oracle,Plsql,Hierarchical Data,我在Oracle10SQL中有一个分层查询,它过去是有效的。然而,我删除了它所基于的物化视图,现在我无法正确地将其显示出来,甚至完全忽略了该视图 原始查询如下所示: select oh.name, oh.description , sys_connect_by_path(groupname, ':') "Groups" , (select count(*) from ml.lastobsmv where lastobsmv.hdid = oh.hdid) as
select oh.name, oh.description
, sys_connect_by_path(groupname, ':') "Groups"
, (select count(*)
from ml.lastobsmv
where lastobsmv.hdid = oh.hdid) as obscount
from ml.obshead oh
join ml.hiergrps hg on oh.groupid = hg.groupid
connect by prior hg.groupid = hg.parentid
我认为它仍然有效,但是如果没有lastobsmv视图,我无法测试它
如果我把它缩小到
select oh.name, oh.description
from ml.obshead oh
join ml.hiergrps hg on oh.groupid = hg.groupid
它仍然有效,返回了41K条记录。然而,当我使用connect by子句时,它会失去控制,返回数百万条记录,在得到准确的计数之前,我通常不得不取消它
select oh.name, oh.description
, sys_connect_by_path(groupname, ':') "Groups"
from ml.obshead oh
join ml.hiergrps hg on oh.groupid = hg.groupid
connect by prior hg.groupid = hg.parentid
我是否错过了一些非常明显的东西,或者我误解了这应该是如何工作的?谢谢
瓦迪姆
它应该返回一个观察术语列表以及它们所在的组。比如说,
障碍:
# CYCLE DAYS, number of days in menstrual cycle, 100
层次结构:
100, 50, Gynecology
50, 10, Tx
10, 0, Basic
应该产生
# CYCLE DAYS, number of days in menstrual cycle, :Basic:Tx:Gynecology
最终,随着obs术语被使用的次数的增加,但我稍后会担心这一点。我不确定您的原始查询如何工作,但这是我得到的最佳解决方案 它返回妇科学:Tx:基本,但顺序相反
SELECT
oh.name,
oh.description,
( SELECT SYS_CONNECT_BY_PATH(groupname, ':')
FROM hiergrps hg
WHERE CONNECT_BY_ISLEAF = 1
START WITH hg.groupid = oh.groupid
CONNECT BY PRIOR hg.parentid = hg.groupid
) "groups"
FROM obshead oh
你真的使用了previor hg.groupid=hg.parentid而不是previor hg.parentid=hg.groupid吗?我可能误解了你的测试数据,但看起来我必须从groupid=100,parentid=50开始,然后得到groupid=50 parentid=10
下面是我用来测试查询的示例数据:
create table obshead
( name varchar2(30)
, description varchar2(30)
, groupid number(3)
);
insert into obshead ( name, description, groupid )
select 'Name One', 'Description One', 100 from dual union all
select 'Name Two', 'Description Two', 200 from dual
;
create table hiergrps
( groupid number(3)
, parentid number(3)
, groupname varchar2(30)
);
insert into hiergrps ( groupid, parentid, groupname )
select 100, 50, 'Gynecology' from dual union all
select 50, 10, 'Tx' from dual union all
select 10, 0, 'Basic' from dual
;
Peter's看起来更优雅,但鉴于以下关于表格和数据的假设,我提出了以下建议:
create table obshead
(
cycledays number,
numdaysincycle number,
groupid number
);
create table hiergrps
(
groupid number,
parent number,
groupname varchar2(40)
);
insert into obshead select 100 cycledays, 30 numdaysincycle, 100 groupid from dual;
insert into hiergrps select 100 groupid, 50 parent, 'Gyncecology' groupname from dual;
insert into hiergrps select 50 groupid, 10 parent, 'Tx' groupname from dual;
insert into hiergrps select 10 groupid, 0 parent, 'Basic' groupname from dual;
select cycledays,
numdaysincycle,
groups
from (select groupid,
parent,
sys_connect_by_path(groupname, ':') groups
from hiergrps hg
start with parent = 0
connect by prior hg.groupid = hg.parent
) hg,
obshead obs
where obs.groupid = hg.groupid;
这对我来说是一种回报:
100 30 :Basic:Tx:Gyncecology
编辑:更新选择以合并Vadim的parentid=0连接似乎是在连接人之前计算的,因此您的一行无法构建层次结构。通过子查询,您将获得所需的内容:
SQL> SELECT oh.NAME, oh.description,
2 MAX(groups) keep(dense_rank LAST ORDER BY lvl) groups
3 FROM obshead oh
4 JOIN (SELECT sys_connect_by_path(groupname, ':') Groups,
5 hg.groupid, hg.parentid, LEVEL lvl
6 FROM hiergrps hg
7 CONNECT BY PRIOR hg.groupid = hg.parentid) hg
8 ON oh.groupid = hg.groupid
9 GROUP BY oh.NAME, oh.description;
NAME DESCRIPTION GROUPS
------------ --------------------------------- ---------------------------
# CYCLE DAYS number of days in menstrual cycle :Basic:Tx:Gynecology
请给我一些观点。如果我们能理解您希望查询做什么,我们都会很乐意提供帮助。您能发布obhead表的描述和一些示例数据,以及hiergrps表的描述和更多的示例数据吗?@sarekoffulcan:我不是在这里挑剔Peter Lang,但您为什么接受他的回答?它不仅以相反的顺序生成Group列,而且在对我的解决方案中的样本数据运行时还会生成一个额外的行。@Vadim:你说得对。我已经换了有记号的答案。我以为你的查询漏掉了一些行,但第二次运行时,我找到了我要查找的行-不知道它们藏在哪里。不过,我不认为它会给我一行额外的数据。啊,从parentid=0开始。我喜欢这样做,这样可以省去获取最大级别的麻烦。+1:我不知道所有条目都是BasicI的childs确实使用了preor group=parent,因为这是文档中的样子:选择姓Employee,按姓ISLEAF ISLEAF连接,level,SYS\u CONNECT\u按姓PATHlast\u连接,来自员工的“/”路径,其中级别I获得ORA-00937:此操作没有任何组功能错误。如果我删除Maxgroups行,它可以正常工作,但这样做会破坏目的-@沙瑞克:我用11gr1测试过。我添加了一个GROUPBY子句,这应该适用于10g
SQL> SELECT oh.NAME, oh.description,
2 MAX(groups) keep(dense_rank LAST ORDER BY lvl) groups
3 FROM obshead oh
4 JOIN (SELECT sys_connect_by_path(groupname, ':') Groups,
5 hg.groupid, hg.parentid, LEVEL lvl
6 FROM hiergrps hg
7 CONNECT BY PRIOR hg.groupid = hg.parentid) hg
8 ON oh.groupid = hg.groupid
9 GROUP BY oh.NAME, oh.description;
NAME DESCRIPTION GROUPS
------------ --------------------------------- ---------------------------
# CYCLE DAYS number of days in menstrual cycle :Basic:Tx:Gynecology