渠道表Channel
——————————————————————————————————
parentid |  id  |  channel
——————————————————————————————————
0 1 运营商
0 2 媒体
1 3 移动
1 4 联通
2 5 报纸
2 6 杂志
6 7 读者文摘
6 8 故事会
5 9 广州日报
5 10 深圳日报
........其实就是如下的一个树形结构根0--
运营商1--
--移动3
--联通4
媒体2 --
--报纸5
--广州日报9
--深圳日报10
--杂志6
--读者文摘7
--故事会8另外一张表

营业记录表A (其中channel_id跟 Channel 表中的 id关联)
——————————————————————————————————
id |   channel_id  |  fee
——————————————————————————————————
1 3  100
2 4  50
3 9  30
4 7  20
5 5  10
6 3  120
7 8  15
8 6  60
9 10  45
10 4  40
11 5  15
12 7  20
13 1  140
14 2  110
........

这张表中,既有channel_id属于广州日报的记录,也有channel_id属于报纸的记录,
既有channel_id属于移动的记录,也有channel_id属于运营商的记录。
也就是说,树形结构中的每个节点(除了根节点0之外)在表A中都有可能有channel_id对应.现在要根据渠道(channel_id)来对营业记录表A进行分组统计费用(fee)
遵循以下规则,  
如果我在界面上选择了根节点为起始节点,那么统计出来的结果应该是运营商 450 (属于运营商这个节点的,并包含其下所有子节点的)
媒体 325 (属于媒体这个节点的,并包含其下所有子节点的)如果我在界面上选择了运营商节点为起始节点,那么统计出来的结果应该是运营商 140 (属于运营商这个节点的)
移动  220 (属于移动这个节点的,并包含其下所有子节点的)
联通 90 (属于联通这个节点的,并包含其下所有子节点的)如果我在界面上选择了媒体节点为起始节点,那么统计出来的结果应该是媒体 110
报纸 100 (属于报纸这个节点的,并包含其下所有子节点的)
杂志 115 (属于杂志这个节点的,并包含其下所有子节点的)也就是说选择某个节点为起始节点,然后统计这个节点下的所有数据,
然后按下一层节点进行分组,同时本节点跟下一层节点列在一起
请问用一句sql怎样写出来呢?

解决方案 »

  1.   

    SQL> select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID;CHANNEL_ID      S_FEE
    ---------- ----------
             1        140
             2        110
             3        220
             4         90
             5         25
             6         60
             7         40
             8         15
             9         30
            10         4510 rows selected.SQL> select * from test_1 t1,
      2  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
      3  where t1.id=t2.CHANNEL_ID;  PARENTID         ID CHANNEL              CHANNEL_ID      S_FEE
    ---------- ---------- -------------------- ---------- ----------
             0          1 运营商                        1        140
             0          2 媒体                          2        110
             1          3 移动                          3        220
             1          4 联通                          4         90
             2          5 报纸                          5         25
             2          6 杂志                          6         60
             6          7 读者文摘                      7         40
             6          8 故事会                        8         15
             5          9 广州日报                      9         30
             5         10 深圳日报                     10         4510 rows selected.SQL> select CHANNEL, S_FEE from (
      2  select * from test_1 t1,
      3  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
      4  where t1.id=t2.CHANNEL_ID
      5  ) where id=0;no rows selectedSQL> select channel, (
      2  select sum(S_FEE) from (select * from test_1 t1,
      3  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
      4  where t1.id=t2.CHANNEL_ID) t2
      5  start with parentid=0 and t2.id=t3.id
      6  connect by PARENTID= prior id
      7  ) fee
      8  from test_1 t3
      9  where parentid=0;CHANNEL                     FEE
    -------------------- ----------
    运营商                      450
    媒体                        325SQL> select CHANNEL, S_FEE from (
      2  select * from test_1 t1,
      3  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
      4  where t1.id=t2.CHANNEL_ID
      5  ) where id=0
      6  union all
      7  select channel, (
      8  select sum(S_FEE) from (select * from test_1 t1,
      9  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
     10  where t1.id=t2.CHANNEL_ID) t2
     11  start with parentid=0 and t2.id=t3.id
     12  connect by PARENTID= prior id
     13  ) fee
     14  from test_1 t3
     15  where parentid=0;CHANNEL                   S_FEE
    -------------------- ----------
    运营商                      450
    媒体                        325
      

  2.   

    SQL> select CHANNEL, S_FEE from (
      2  select * from test_1 t1,
      3  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
      4  where t1.id=t2.CHANNEL_ID
      5  ) where id=1
      6  union all
      7  select channel, (
      8  select sum(S_FEE) from (select * from test_1 t1,
      9  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
     10  where t1.id=t2.CHANNEL_ID) t2
     11  start with parentid=t3.parentid and t2.id=t3.id
     12  connect by PARENTID= prior id
     13  ) fee
     14  from test_1 t3
     15  where parentid=1;CHANNEL                   S_FEE
    -------------------- ----------
    运营商                      140
    移动                        220
    联通                         90SQL> select CHANNEL, S_FEE from (
      2  select * from test_1 t1,
      3  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
      4  where t1.id=t2.CHANNEL_ID
      5  ) where id=2
      6  union all
      7  select channel, (
      8  select sum(S_FEE) from (select * from test_1 t1,
      9  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
     10  where t1.id=t2.CHANNEL_ID) t2
     11  start with parentid=t3.parentid and t2.id=t3.id
     12  connect by PARENTID= prior id
     13  ) fee
     14  from test_1 t3
     15  where parentid=2;CHANNEL                   S_FEE
    -------------------- ----------
    媒体                        110
    报纸                        100
    杂志                        115SQL> select CHANNEL, S_FEE from (
      2  select * from test_1 t1,
      3  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
      4  where t1.id=t2.CHANNEL_ID
      5  ) where id=5
      6  union all
      7  select channel, (
      8  select sum(S_FEE) from (select * from test_1 t1,
      9  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
     10  where t1.id=t2.CHANNEL_ID) t2
     11  start with parentid=t3.parentid and t2.id=t3.id
     12  connect by PARENTID= prior id
     13  ) fee
     14  from test_1 t3
     15  where parentid=5;CHANNEL                   S_FEE
    -------------------- ----------
    报纸                         25
    广州日报                     30
    深圳日报                     45SQL> select CHANNEL, S_FEE from (
      2  select * from test_1 t1,
      3  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
      4  where t1.id=t2.CHANNEL_ID
      5  ) where id=6
      6  union all
      7  select channel, (
      8  select sum(S_FEE) from (select * from test_1 t1,
      9  (select CHANNEL_ID, sum(FEE) s_fee from test_2 group by CHANNEL_ID) t2
     10  where t1.id=t2.CHANNEL_ID) t2
     11  start with parentid=t3.parentid and t2.id=t3.id
     12  connect by PARENTID= prior id
     13  ) fee
     14  from test_1 t3
     15  where parentid=6;CHANNEL                   S_FEE
    -------------------- ----------
    杂志                         60
    读者文摘                     40
    故事会                       15