sql – 计算其父项所有根的百分比

简单来说,我试图计算其父母所拥有的树的根百分比,进一步增加树.如何在sql中单独执行此操作?

这是我的(示例)模式.请注意,虽然层次结构本身非常简单,但是还有一个additional_id,这意味着单个父级可以“拥有”他们孩子的不同部分.

create table hierarchy_test ( 
       id number -- "root" ID,parent_id number -- Parent of ID,holding_id number -- The ID can be split into multiple parts,percent_owned number (3,2),primary key (id,parent_id,holding_id) 
        );

和一些样本数据:

insert all 
 into hierarchy_test values (1,2,1,1) 
 into hierarchy_test values (2,3,0.25)
 into hierarchy_test values (2,4,5,0.1)
 into hierarchy_test values (2,0.4)
 into hierarchy_test values (4,1)
 into hierarchy_test values (5,6,0.3)
 into hierarchy_test values (5,7,0.2)
 into hierarchy_test values (5,8,0.5)
select * from dual;

SQL Fiddle

以下查询返回我想要的计算.由于SYS_CONNECT_BY_PATH的性质,据我所知,它不能执行计算.

select a.*,level as lvl,'1' || sys_connect_by_path(percent_owned,' * ') as calc
   from hierarchy_test a
  start with id = 1
connect by nocycle prior parent_id = id

数据中有周期性的关系,在这个例子中就没有.

目前,我将使用一个非常简单的函数将calc列中的字符串转换成数字

create or replace function some_sum ( P_Sum in varchar2 ) return number is
   l_result number;
begin  
   execute immediate 'select ' || P_Sum || ' from dual'
     into l_result;

   return l_result;   
end;
/

这似乎是一个可笑的方法,我宁愿避免额外的时间将解析动态sql1.

理论上,我想,我应该可以使用MODEL子句来计算.我的问题是由树的非唯一性造成的.我尝试使用MODEL子句来做到这一点:

select *
  from ( select a.*,' * ') as calc
           from hierarchy_test a
          start with id = 1
        connect by nocycle prior parent_id = id
                 )
 model
 dimension by (lvl ll,id ii)
 measures (percent_owned,parent_id )
 rules upsert all ( 
   percent_owned[any,any]
   order by ll,ii  = percent_owned[cv(ll),cv(ii)] * nvl( percent_owned[cv(ll) - 1,parent_id[cv(ll),cv(ii)]],1)
               )

这可以理解,失败如下:

ORA-32638: Non unique addressing in MODEL dimensions

由于类似的原因,使用UNIQUE SINGLE REFERENCE失败,即ORDER BY子句不是唯一的.

TL;博士

有没有一种简单的方法来计算其父母所拥有的树的根百分比,只使用sql?如果我跟MODEL在正确的轨道上出现错误

我也想避免PL / sql sql上下文切换.我意识到这是一个很短的时间,但这将很难做到,而不需要每天添加几分钟.

解决方法

在11g,可能是像 –
SELECT a.*,LEVEL AS lvl,XMLQuery( substr( sys_connect_by_path( percent_owned,'*' ),2 ) RETURNING CONTENT).getnumberval() AS calc
   FROM hierarchy_test a
  START WITH id = 1
CONNECT BY nocycle PRIOR parent_id = id;

SQL Fiddle.

或者,根据你的’1’||招-

SELECT a.*,XMLQuery( ('1'|| sys_connect_by_path( percent_owned,'*' )) RETURNING CONTENT).getnumberval() AS calc
   FROM hierarchy_test a
  START WITH id = 1
CONNECT BY nocycle PRIOR parent_id = id;

不幸的是在10g中,XMLQuery不能接受函数,并且总是期望一个字符串字面值用于评估,例如 –

select XMLQuery('1*0.25' RETURNING CONTENT).getnumberval() as val 
  from dual;

工作和回报0.25,但

select XMLQuery(substr('*1*0.25',2) RETURNING CONTENT).getnumberval() as val
   from dual;

给出了ORA-19102:预期的XQuery字符串字面值.

随着树的级数增加,XMLQuery本身的内部树创建的额外开销也会增加查询速度.实现结果的最佳方法仍然是PL / sql函数,它在10g和11g中都可以使用.

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 'EastRiver' 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...