微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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中都可以使用.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_no='LJCG001H' THEN dbo.ELTPNAME(a.fw_nu) ELSE d.fm_name END),e.fw_state_nm,f.fw_rmk_nm
if not exists(select name from syscolumns where name='tod_no' and id=object_id('iebo09d12')) alter table iebo09d12 add tod_no varchar(
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_nm,g.fa_name from LJSS007H a (nolock) Left join LJPA002H b (nolock) On a.pa_no =b.pa_no Left jo
要在 SQL Server 2019 中设置定时自动重启,可以使用 Windows 任务计划程序。下面是详细的步骤: 步骤一:创建批处理文件 打开记事本。 输入以下内容: net stop "SQL Server (MSSQLSERVER)" net start "SQ
您收到的错误消息表明数据库 'EastRiver' 的事务日志已满,导致数据库操作失败。要解决这个问题,可以按照以下步骤操作: 1. 备份事务日志首先,备份事务日志以释放空间: BACKUP LOG [EastRiver] TO DISK = N'C:\Backup\East
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标识ID,若不知道怎么查询数据库的标识ID, 打开SQL Server management studio,点击工具。选择SQL Server Profiler。 登录,登录成功后,如果有个默认弹窗,先取消 新建追踪 命名
--最新的解决方法 --先创建用户帐户,不进行授权,然后通过下面的SQL语句将该用户帐户关联至对应的数据库用户。优点是避免了重新授权的操作。 USE tempdbEXEC sp_change_users_login 'Update_One', 'iemis', &#3
命令: ALTER TABLE 表名 add 列名 数据类型 default 默认值 not null 例如: ALTER TABLE LJEL005H add el_req int default 15 not null
declare @i int set @i=340 while @i<415 begin set @i=@iʱ insert into LJWK007H select '2024','28','9110','3PTSD621000000