oracle高级递归结算,求写法!!!

ksdy138141314 2016-05-26 03:38:28
表和数据:
with table1 as (
select 'A' as parent_no, 'B' as no from dual union all
select 'A' as parent_no, 'C' as no from dual union all
select 'B' as parent_no, 'D' as no from dual union all
select 'C' as parent_no, 'E' as no from dual union all
select 'A' as parent_no, 'F' as no from dual union all
select 'C' as parent_no, 'G' as no from dual union all
select 'G' as parent_no, 'H' as no from dual
),
table2 as (
select 'A' AS NO,3 AS no_level from dual union all
select 'B' AS NO,NULL AS no_level from dual union all
select 'C' AS NO,2 AS no_level from dual union all
select 'D' AS NO,null AS no_level from dual union all
select 'E' AS NO,null AS no_level from dual union all
select 'F' AS NO,1 AS no_level from dual union all
select 'G' AS NO,2 AS no_level from dual union all
select 'H' AS NO,null AS no_level from dual
),
table3 as (
select 'A' as no,100 as money from dual union all
select 'B' as no,200 as money from dual union all
select 'C' as no,300 as money from dual union all
select 'D' as no,400 as money from dual union all
select 'E' as no,500 as money from dual union all
select 'F' as no,600 as money from dual union all
select 'G' as no,700 as money from dual union all
select 'H' as no,800 as money from dual
)



关系图:


有如上3张表,table1表示用户之间的关系,table2表示用户的等级,table3表示用户的钱。


现在需要结算有等级的用户(没有等级的用户没有提成),比如A用户等级是3,那A用户就根据这个关系,提下级用户的成,提成规则如下:
其他用户都是A用户的下级,A的等级为3,表示A需要提成3个层级的用户。但这个层级不是图中看到的层级关系。因为A的下级用户C,F,G都有等级,提成第一层money的时候,提B,C,F 三个用户的money,提成第二层money的时候,提E,G,提成第三层money的时候,提H用户的money。

说明一下,提成第一层的时候,没有悬念。提成第二层的时候,为什么只提成E,G,不提成D呢??因为D的直属是B,而B没有等级,所以在提成第一层B的时候,就已经计算过B的直属下级没有等级会员的money,就不能重复提D了。E也没有等级,但E的直属上级C有等级,在提成C的时候,因为C有等级,所以只提了C。C的所有下级并没有提,所以在提成第二层的时候,E就要提成了。G也一样需要提成。那为什么在提成第二层的时候,H没有提成?因为G有等级。所以有等级的用户,只能提自己的money,如果用户等级够高,还能继续往下提成,就可以提H用户的money。但如果图中还有一个用户I是E的下级且没有等级,那提成第三层的时候,是不能提I用户的。因为I用户的money已经算在E用户里面了。

A的期望结果:

用户 所得提成(比如提成都是5%) 提供提成的会员
A 10 B
A 15 C
A 30 F
A 25 E
A 35 G
A 40 H

PS: 如果可以一个sql更好,可以多个sql
...全文
188 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
ghx287524027 2016-05-27
  • 打赏
  • 举报
回复

with table1 as
(select 'A' as parent_no, 'B' as no from dual union all
select 'A' as parent_no, 'C' as no from dual union all
select 'B' as parent_no, 'D' as no from dual union all
select 'C' as parent_no, 'E' as no from dual union all
select 'A' as parent_no, 'F' as no from dual union all
select 'C' as parent_no, 'G' as no from dual union all
select 'G' as parent_no, 'H' as no from dual union all
select 'H' as parent_no, 'I' as no from dual),
table2 as
(select 'A' AS NO, 3 AS no_level from dual union all
select 'B' AS NO, NULL AS no_level from dual union all
select 'C' AS NO, 2 AS no_level from dual union all
select 'D' AS NO, null AS no_level from dual union all
select 'E' AS NO, null AS no_level from dual union all
select 'F' AS NO, 1 AS no_level from dual union all
select 'G' AS NO, 2 AS no_level from dual union all
select 'H' AS NO, null AS no_level from dual UNION ALL
select 'I' AS NO, 1 AS no_level from dual),
table3 as
(select 'A' as no, 100 as money from dual union all
select 'B' as no, 200 as money from dual union all
select 'C' as no, 300 as money from dual union all
select 'D' as no, 400 as money from dual union all
select 'E' as no, 500 as money from dual union all
select 'F' as no, 600 as money from dual union all
select 'G' as no, 700 as money from dual union all
select 'H' as no, 800 as money from dual UNION ALL
select 'I' as no, 900 as money from dual)
,
table4 as
(
select CONNECT_BY_ROOT(a.parent_no) root, a.no, level lv
from (select b.parent_no,b.no from table1 b where b.parent_no in (select c.no from table2 c where c.no=b.parent_no and c.no_level is not null)) a
connect by prior a.no = a.parent_no
union all
select a.no root,a.no,1 as lv from table2 a
where a.no_level is not null and a.no not in (select parent_no from table1 )
)

select t4.root, t4.no, t3.money * 0.05 as money
from table4 t4, table1 t1, table2 t2, table3 t3
where t4.no = t1.no
and t1.parent_no = t2.no
and t1.no = t3.no
and (lv = 1 or (lv > 1 and not t2.no_level is null))


结果如下:

ksdy138141314 2016-05-27
  • 打赏
  • 举报
回复
如果E下面有个用户J,J没有等级的话,那A是取不到J的,因为在取E的时候,就已经把J算进去了。
引用 6 楼 ghx287524027 的回复:
A能不能提取到I 呢?
ksdy138141314 2016-05-27
  • 打赏
  • 举报
回复
引用 6 楼 ghx287524027 的回复:
A能不能提取到I 呢?
可以取到,取到I这个用户的money
ghx287524027 2016-05-27
  • 打赏
  • 举报
回复
A能不能提取到I 呢?
ksdy138141314 2016-05-27
  • 打赏
  • 举报
回复
引用 4 楼 ghx287524027 的回复:
[quote=引用 3 楼 ksdy138141314 的回复:] [quote=引用 1 楼 snbxp 的回复:]

with table1 as
 (select 'A' as parent_no, 'B' as no from dual union all
  select 'A' as parent_no, 'C' as no from dual union all
  select 'B' as parent_no, 'D' as no from dual union all
  select 'C' as parent_no, 'E' as no from dual union all
  select 'A' as parent_no, 'F' as no from dual union all
  select 'C' as parent_no, 'G' as no from dual union all
  select 'G' as parent_no, 'H' as no from dual),
table2 as
 (select 'A' AS NO, 3 AS no_level from dual union all
  select 'B' AS NO, NULL AS no_level from dual union all
  select 'C' AS NO, 2 AS no_level from dual union all
  select 'D' AS NO, null AS no_level from dual union all
  select 'E' AS NO, null AS no_level from dual union all
  select 'F' AS NO, 1 AS no_level from dual union all
  select 'G' AS NO, 2 AS no_level from dual union all
  select 'H' AS NO, null AS no_level from dual),
table3 as
 (select 'A' as no, 100 as money from dual union all
  select 'B' as no, 200 as money from dual union all
  select 'C' as no, 300 as money from dual union all
  select 'D' as no, 400 as money from dual union all
  select 'E' as no, 500 as money from dual union all
  select 'F' as no, 600 as money from dual union all
  select 'G' as no, 700 as money from dual union all
  select 'H' as no, 800 as money from dual),
table4 as
(
select CONNECT_BY_ROOT(parent_no) root, no, level lv
  from table1 a
connect by prior no = a.parent_no
)
select t4.root, t4.no, t3.money * 0.05
  from table4 t4, table1 t1, table2 t2, table3 t3
 where t4.no = t1.no
   and t1.parent_no = t2.no
   and t1.no = t3.no
   and (lv = 1 or (lv > 1 and not t2.no_level is null))
   and t4.root='A'

首先感谢哥们,但我发现有一种情况没有统计到。如果H用户下面还有一个有等级的用户I。按照你给的sql。统计不到I用户的提成,数据如下:
with table1 as
 (select 'A' as parent_no, 'B' as no from dual union all
  select 'A' as parent_no, 'C' as no from dual union all
  select 'B' as parent_no, 'D' as no from dual union all
  select 'C' as parent_no, 'E' as no from dual union all
  select 'A' as parent_no, 'F' as no from dual union all
  select 'C' as parent_no, 'G' as no from dual union all
  select 'G' as parent_no, 'H' as no from dual union all
  select 'H' as parent_no, 'I' as no from dual),
table2 as
 (select 'A' AS NO, 3 AS no_level from dual union all
  select 'B' AS NO, NULL AS no_level from dual union all
  select 'C' AS NO, 2 AS no_level from dual union all
  select 'D' AS NO, null AS no_level from dual union all
  select 'E' AS NO, null AS no_level from dual union all
  select 'F' AS NO, 1 AS no_level from dual union all
  select 'G' AS NO, 2 AS no_level from dual union all
  select 'H' AS NO, null AS no_level from dual UNION ALL
  select 'I' AS NO, 1 AS no_level from dual),
table3 as
 (select 'A' as no, 100 as money from dual union all
  select 'B' as no, 200 as money from dual union all
  select 'C' as no, 300 as money from dual union all
  select 'D' as no, 400 as money from dual union all
  select 'E' as no, 500 as money from dual union all
  select 'F' as no, 600 as money from dual union all
  select 'G' as no, 700 as money from dual union all
  select 'H' as no, 800 as money from dual UNION ALL
  select 'I' as no, 900 as money from dual)
[/quote] 如果I在H下面,那么要提取I的话,H不应该要有等级的吗?[/quote] 要不要提取奖金,和下级会员的等级没关系,只要能提这么多层就可以。提G这个用户的时候,只提了G这个点,提H这个用户的时候,如果下级用户I有等级,那也只能提H用户这个点,如果还能提下一层,那就是I这个点。
ghx287524027 2016-05-27
  • 打赏
  • 举报
回复
引用 3 楼 ksdy138141314 的回复:
[quote=引用 1 楼 snbxp 的回复:]

with table1 as
 (select 'A' as parent_no, 'B' as no from dual union all
  select 'A' as parent_no, 'C' as no from dual union all
  select 'B' as parent_no, 'D' as no from dual union all
  select 'C' as parent_no, 'E' as no from dual union all
  select 'A' as parent_no, 'F' as no from dual union all
  select 'C' as parent_no, 'G' as no from dual union all
  select 'G' as parent_no, 'H' as no from dual),
table2 as
 (select 'A' AS NO, 3 AS no_level from dual union all
  select 'B' AS NO, NULL AS no_level from dual union all
  select 'C' AS NO, 2 AS no_level from dual union all
  select 'D' AS NO, null AS no_level from dual union all
  select 'E' AS NO, null AS no_level from dual union all
  select 'F' AS NO, 1 AS no_level from dual union all
  select 'G' AS NO, 2 AS no_level from dual union all
  select 'H' AS NO, null AS no_level from dual),
table3 as
 (select 'A' as no, 100 as money from dual union all
  select 'B' as no, 200 as money from dual union all
  select 'C' as no, 300 as money from dual union all
  select 'D' as no, 400 as money from dual union all
  select 'E' as no, 500 as money from dual union all
  select 'F' as no, 600 as money from dual union all
  select 'G' as no, 700 as money from dual union all
  select 'H' as no, 800 as money from dual),
table4 as
(
select CONNECT_BY_ROOT(parent_no) root, no, level lv
  from table1 a
connect by prior no = a.parent_no
)
select t4.root, t4.no, t3.money * 0.05
  from table4 t4, table1 t1, table2 t2, table3 t3
 where t4.no = t1.no
   and t1.parent_no = t2.no
   and t1.no = t3.no
   and (lv = 1 or (lv > 1 and not t2.no_level is null))
   and t4.root='A'

首先感谢哥们,但我发现有一种情况没有统计到。如果H用户下面还有一个有等级的用户I。按照你给的sql。统计不到I用户的提成,数据如下:
with table1 as
 (select 'A' as parent_no, 'B' as no from dual union all
  select 'A' as parent_no, 'C' as no from dual union all
  select 'B' as parent_no, 'D' as no from dual union all
  select 'C' as parent_no, 'E' as no from dual union all
  select 'A' as parent_no, 'F' as no from dual union all
  select 'C' as parent_no, 'G' as no from dual union all
  select 'G' as parent_no, 'H' as no from dual union all
  select 'H' as parent_no, 'I' as no from dual),
table2 as
 (select 'A' AS NO, 3 AS no_level from dual union all
  select 'B' AS NO, NULL AS no_level from dual union all
  select 'C' AS NO, 2 AS no_level from dual union all
  select 'D' AS NO, null AS no_level from dual union all
  select 'E' AS NO, null AS no_level from dual union all
  select 'F' AS NO, 1 AS no_level from dual union all
  select 'G' AS NO, 2 AS no_level from dual union all
  select 'H' AS NO, null AS no_level from dual UNION ALL
  select 'I' AS NO, 1 AS no_level from dual),
table3 as
 (select 'A' as no, 100 as money from dual union all
  select 'B' as no, 200 as money from dual union all
  select 'C' as no, 300 as money from dual union all
  select 'D' as no, 400 as money from dual union all
  select 'E' as no, 500 as money from dual union all
  select 'F' as no, 600 as money from dual union all
  select 'G' as no, 700 as money from dual union all
  select 'H' as no, 800 as money from dual UNION ALL
  select 'I' as no, 900 as money from dual)
[/quote] 如果I在H下面,那么要提取I的话,H不应该要有等级的吗?
ghx287524027 2016-05-27
  • 打赏
  • 举报
回复

with table1 as
 (select 'A' as parent_no, 'B' as no from dual union all
  select 'A' as parent_no, 'C' as no from dual union all
  select 'B' as parent_no, 'D' as no from dual union all
  select 'C' as parent_no, 'E' as no from dual union all
  select 'A' as parent_no, 'F' as no from dual union all
  select 'C' as parent_no, 'G' as no from dual union all
  select 'G' as parent_no, 'H' as no from dual union all
  select 'H' as parent_no, 'I' as no from dual),
table2 as
 (select 'A' AS NO, 3 AS no_level from dual union all
  select 'B' AS NO, NULL AS no_level from dual union all
  select 'C' AS NO, 2 AS no_level from dual union all
  select 'D' AS NO, null AS no_level from dual union all
  select 'E' AS NO, null AS no_level from dual union all
  select 'F' AS NO, 1 AS no_level from dual union all
  select 'G' AS NO, 2 AS no_level from dual union all
  select 'H' AS NO, null AS no_level from dual UNION ALL
  select 'I' AS NO, 1 AS no_level from dual),
table3 as
 (select 'A' as no, 100 as money from dual union all
  select 'B' as no, 200 as money from dual union all
  select 'C' as no, 300 as money from dual union all
  select 'D' as no, 400 as money from dual union all
  select 'E' as no, 500 as money from dual union all
  select 'F' as no, 600 as money from dual union all
  select 'G' as no, 700 as money from dual union all
  select 'H' as no, 800 as money from dual UNION ALL
  select 'I' as no, 900 as money from dual)
,
table4 as
(
select b.root,b.no,b.lv from
(select CONNECT_BY_ROOT(a.parent_no) root, a.no, level lv
  from table1 a
connect by prior a.no = a.parent_no ) b
where b.root in (select c.no from table2 c where c.no=b.root and c.no_level is not null)
)
  
select distinct t4.root, t4.no, t3.money * 0.05 as money
  from table4 t4, table1 t1, table2 t2, table3 t3
 where t4.no = t1.no
   and t1.no = t3.no
   and ((t1.parent_no = t2.no and t2.no_level is not null) or (t4.no=t2.no and t2.no_level is not null))
ksdy138141314 2016-05-26
  • 打赏
  • 举报
回复
引用 1 楼 snbxp 的回复:

with table1 as
 (select 'A' as parent_no, 'B' as no from dual union all
  select 'A' as parent_no, 'C' as no from dual union all
  select 'B' as parent_no, 'D' as no from dual union all
  select 'C' as parent_no, 'E' as no from dual union all
  select 'A' as parent_no, 'F' as no from dual union all
  select 'C' as parent_no, 'G' as no from dual union all
  select 'G' as parent_no, 'H' as no from dual),
table2 as
 (select 'A' AS NO, 3 AS no_level from dual union all
  select 'B' AS NO, NULL AS no_level from dual union all
  select 'C' AS NO, 2 AS no_level from dual union all
  select 'D' AS NO, null AS no_level from dual union all
  select 'E' AS NO, null AS no_level from dual union all
  select 'F' AS NO, 1 AS no_level from dual union all
  select 'G' AS NO, 2 AS no_level from dual union all
  select 'H' AS NO, null AS no_level from dual),
table3 as
 (select 'A' as no, 100 as money from dual union all
  select 'B' as no, 200 as money from dual union all
  select 'C' as no, 300 as money from dual union all
  select 'D' as no, 400 as money from dual union all
  select 'E' as no, 500 as money from dual union all
  select 'F' as no, 600 as money from dual union all
  select 'G' as no, 700 as money from dual union all
  select 'H' as no, 800 as money from dual),
table4 as
(
select CONNECT_BY_ROOT(parent_no) root, no, level lv
  from table1 a
connect by prior no = a.parent_no
)
select t4.root, t4.no, t3.money * 0.05
  from table4 t4, table1 t1, table2 t2, table3 t3
 where t4.no = t1.no
   and t1.parent_no = t2.no
   and t1.no = t3.no
   and (lv = 1 or (lv > 1 and not t2.no_level is null))
   and t4.root='A'

首先感谢哥们,但我发现有一种情况没有统计到。如果H用户下面还有一个有等级的用户I。按照你给的sql。统计不到I用户的提成,数据如下:
with table1 as
 (select 'A' as parent_no, 'B' as no from dual union all
  select 'A' as parent_no, 'C' as no from dual union all
  select 'B' as parent_no, 'D' as no from dual union all
  select 'C' as parent_no, 'E' as no from dual union all
  select 'A' as parent_no, 'F' as no from dual union all
  select 'C' as parent_no, 'G' as no from dual union all
  select 'G' as parent_no, 'H' as no from dual union all
  select 'H' as parent_no, 'I' as no from dual),
table2 as
 (select 'A' AS NO, 3 AS no_level from dual union all
  select 'B' AS NO, NULL AS no_level from dual union all
  select 'C' AS NO, 2 AS no_level from dual union all
  select 'D' AS NO, null AS no_level from dual union all
  select 'E' AS NO, null AS no_level from dual union all
  select 'F' AS NO, 1 AS no_level from dual union all
  select 'G' AS NO, 2 AS no_level from dual union all
  select 'H' AS NO, null AS no_level from dual UNION ALL
  select 'I' AS NO, 1 AS no_level from dual),
table3 as
 (select 'A' as no, 100 as money from dual union all
  select 'B' as no, 200 as money from dual union all
  select 'C' as no, 300 as money from dual union all
  select 'D' as no, 400 as money from dual union all
  select 'E' as no, 500 as money from dual union all
  select 'F' as no, 600 as money from dual union all
  select 'G' as no, 700 as money from dual union all
  select 'H' as no, 800 as money from dual UNION ALL
  select 'I' as no, 900 as money from dual)
ksdy138141314 2016-05-26
  • 打赏
  • 举报
回复
引用 1 楼 snbxp 的回复:

with table1 as
 (select 'A' as parent_no, 'B' as no from dual union all
  select 'A' as parent_no, 'C' as no from dual union all
  select 'B' as parent_no, 'D' as no from dual union all
  select 'C' as parent_no, 'E' as no from dual union all
  select 'A' as parent_no, 'F' as no from dual union all
  select 'C' as parent_no, 'G' as no from dual union all
  select 'G' as parent_no, 'H' as no from dual),
table2 as
 (select 'A' AS NO, 3 AS no_level from dual union all
  select 'B' AS NO, NULL AS no_level from dual union all
  select 'C' AS NO, 2 AS no_level from dual union all
  select 'D' AS NO, null AS no_level from dual union all
  select 'E' AS NO, null AS no_level from dual union all
  select 'F' AS NO, 1 AS no_level from dual union all
  select 'G' AS NO, 2 AS no_level from dual union all
  select 'H' AS NO, null AS no_level from dual),
table3 as
 (select 'A' as no, 100 as money from dual union all
  select 'B' as no, 200 as money from dual union all
  select 'C' as no, 300 as money from dual union all
  select 'D' as no, 400 as money from dual union all
  select 'E' as no, 500 as money from dual union all
  select 'F' as no, 600 as money from dual union all
  select 'G' as no, 700 as money from dual union all
  select 'H' as no, 800 as money from dual),
table4 as
(
select CONNECT_BY_ROOT(parent_no) root, no, level lv
  from table1 a
connect by prior no = a.parent_no
)
select t4.root, t4.no, t3.money * 0.05
  from table4 t4, table1 t1, table2 t2, table3 t3
 where t4.no = t1.no
   and t1.parent_no = t2.no
   and t1.no = t3.no
   and (lv = 1 or (lv > 1 and not t2.no_level is null))
   and t4.root='A'

非常感谢,我替换到开发环境中看看实际的数据。先谢过
snbxp 2016-05-26
  • 打赏
  • 举报
回复

with table1 as
 (select 'A' as parent_no, 'B' as no from dual union all
  select 'A' as parent_no, 'C' as no from dual union all
  select 'B' as parent_no, 'D' as no from dual union all
  select 'C' as parent_no, 'E' as no from dual union all
  select 'A' as parent_no, 'F' as no from dual union all
  select 'C' as parent_no, 'G' as no from dual union all
  select 'G' as parent_no, 'H' as no from dual),
table2 as
 (select 'A' AS NO, 3 AS no_level from dual union all
  select 'B' AS NO, NULL AS no_level from dual union all
  select 'C' AS NO, 2 AS no_level from dual union all
  select 'D' AS NO, null AS no_level from dual union all
  select 'E' AS NO, null AS no_level from dual union all
  select 'F' AS NO, 1 AS no_level from dual union all
  select 'G' AS NO, 2 AS no_level from dual union all
  select 'H' AS NO, null AS no_level from dual),
table3 as
 (select 'A' as no, 100 as money from dual union all
  select 'B' as no, 200 as money from dual union all
  select 'C' as no, 300 as money from dual union all
  select 'D' as no, 400 as money from dual union all
  select 'E' as no, 500 as money from dual union all
  select 'F' as no, 600 as money from dual union all
  select 'G' as no, 700 as money from dual union all
  select 'H' as no, 800 as money from dual),
table4 as
(
select CONNECT_BY_ROOT(parent_no) root, no, level lv
  from table1 a
connect by prior no = a.parent_no
)
select t4.root, t4.no, t3.money * 0.05
  from table4 t4, table1 t1, table2 t2, table3 t3
 where t4.no = t1.no
   and t1.parent_no = t2.no
   and t1.no = t3.no
   and (lv = 1 or (lv > 1 and not t2.no_level is null))
   and t4.root='A'

3,491

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧