求逐级向上汇总

--公司信息表

CREATE TABLE TEST_COMPANYINFO

(

COMPID  VARCHAR2(30), --公司

COMPNAME VARCHAR2(200), --公司名

PCOMPID VARCHAR2(30)  --上级公司

);

--物品信息表

CREATE TABLE TEST_PRODUCTINFO

(

PRODID  VARCHAR2(20), --物品

COMPID VARCHAR2(30),  --公司

NUM  NUMBER(6)   --数量

);

INSERT INTO TEST_COMPANYINFO VALUES ('0100','可口可乐广东省公司',NULL);

INSERT INTO TEST_COMPANYINFO VALUES ('0200','可口可乐深圳公司','0100');

INSERT INTO TEST_COMPANYINFO VALUES ('0300','福田区可口可乐分公司','0200');

INSERT INTO TEST_COMPANYINFO VALUES ('0301','南山区可口可乐分公司','0200');

INSERT INTO TEST_COMPANYINFO VALUES ('0302','宝安区可口可乐分分公司','0200');

INSERT INTO TEST_COMPANYINFO VALUES ('0210','可口可乐珠海公司','0100');

INSERT INTO TEST_COMPANYINFO VALUES ('0320','吉大区可口可乐分公司','0210');

INSERT INTO TEST_COMPANYINFO VALUES ('0330','香洲区可口可乐分公司','0210');

INSERT INTO TEST_COMPANYINFO VALUES ('0340','拱北区可口可乐分分公司','0210');

INSERT INTO TEST_PRODUCTINFO (PRODID, COMPID, NUM)

VALUES ('1000001''0300'50);

INSERT INTO TEST_PRODUCTINFO (PRODID, COMPID, NUM)

VALUES ('1000001''0301'60);

INSERT INTO  TEST_PRODUCTINFO (PRODID, COMPID, NUM)

VALUES ('1000001''0302'70);

INSERT INTO TEST_PRODUCTINFO (PRODID, COMPID, NUM)

VALUES ('1000002''0300'50);

INSERT INTO TEST_PRODUCTINFO (PRODID, COMPID, NUM)

VALUES ('1000002''0301'60);

INSERT INTO  TEST_PRODUCTINFO (PRODID, COMPID, NUM)

VALUES ('1000002''0302'70);

INSERT INTO TEST_PRODUCTINFO (PRODID, COMPID, NUM)

VALUES ('1000002''0340'50);

INSERT INTO TEST_PRODUCTINFO (PRODID, COMPID, NUM)

VALUES ('1000001''0320'60);

INSERT INTO  TEST_PRODUCTINFO (PRODID, COMPID, NUM)

VALUES ('1000003''0330'70);

INSERT INTO  TEST_PRODUCTINFO (PRODID, COMPID, NUM)

VALUES ('1000003''0320'70); 

方法一、select t3.prodid,compid,t3.num,compname from

(select sum(t2.num) num, prodid,pcompid from

(select t1.prodid,compid,t1.num,compname,c.pcompid from(select sum(t.num) num, prodid,pcompid from 

(select p.*,pcompid,compname from TEST_COMPANYINFO c,TEST_PRODUCTINFO p where c.compid=p.compid) t  

group by prodid,pcompid) t1,TEST_COMPANYINFO c where c.compid=t1.pcompid) t2 group by prodid,pcompid) t3,TEST_COMPANYINFO c 

where c.compid=t3.pcompid --

union 

(select t1.prodid,compid,t1.num,compname from(select sum(t.num) num, prodid,pcompid from 

(select p.*,pcompid,compname from TEST_COMPANYINFO c,TEST_PRODUCTINFO p where c.compid=p.compid) t  

group by prodid,pcompid) t1,TEST_COMPANYINFO c where c.compid=t1.pcompid)--

union 

(select p.*,compname from TEST_COMPANYINFO c,TEST_PRODUCTINFO p where c.compid=p.compid )--

方法二、

with t as (

                 select compid,node

                    from (

                           select compid,substr(sub_node,instr(sub_node,'/',1,1)+1,instr(sub_node,'/',1,2) - instr(sub_node,'/',1,1) -1) node

                            from (

                                   select compid,sys_connect_by_path(compid,'/')||'/' sub_node

                                     from test_companyinfo

                                  connect by  compid = prior pcompid

                                 )

                        )

                where node in (

                                 select distinct compid

                                   from test_companyinfo

                                  where connect_by_isleaf = 1

                                connect by prior compid =  pcompid

                              )

             )

  select t.compid,(select compname from test_companyinfo where compid= t.compid) compname,

         b.prodid,

         sum(b.num)

    from t,test_productinfo b

   where t.node = b.compid

   group by t.compid,b.prodid

   order by t.compid,b.prodid

具体参见图示:

方法三、树结构查询

select a.*,b.num  ,

case when sum(numover(partition by a.compid,compname,pcompid order by nullis null 

then sum(nvl(num,0)) over(partition by  decode(level,2,a.compid,pcompid) order by a.compid desc) +

decode(level,1,sum(nvl(num,0)) over(partition by  null order by  null),0)

else sum(numover(partition by a.compid,compname,pcompid order by null)

end 

from TEST_COMPANYINFO a left join TEST_PRODUCTINFO b on a.compid=b.compid

start with pcompid is null

CONNECT BY   PCOMPID = PRIOR  a.COMPID

方法四、树状结构查询

WITH v_base_ma AS (  SELECT prodid pid, compid cid, SUM (num) ma

                       FROM TEST_PRODUCTINFO

                   GROUP BY prodid, compid

                     HAVING SUM (num) > 0),

     v_comp

        AS (SELECT DISTINCT COMPID cid, COMPNAME cname FROM TEST_COMPANYINFO),

     v_prod AS (SELECT DISTINCT prodid pid FROM TEST_PRODUCTINFO),

OD AS (     

SELECT COMPID,LEVEL LV

FROM TEST_COMPANYINFO

START WITH TRIM(PCOMPID) IS NULL

CONNECT BY PCOMPID = PRIOR COMPID)

  SELECT A.*,LV

    FROM (SELECT a.cid,

                 a.cname,

                 a.pid,

                 ma

            FROM (SELECT a.cid,

                         a.cname,

                         b.pid,

                         (SELECT NVL (SUM (ma), 0) ma

                            FROM v_base_ma t

                           WHERE t.pid = b.pid

                                 AND t.cid IN

                                        (    SELECT COMPID

                                               FROM TEST_COMPANYINFO

                                         START WITH PCOMPID = a.cid

                                         CONNECT BY PCOMPID = PRIOR COMPID))

                            ma

                    FROM v_comp a, v_prod b) a

           WHERE ma > 0

          UNION ALL

          SELECT l.cid,

                 cname,

                 pid,

                 ma

            FROM v_base_ma l, v_comp e

           WHERE l.cid = e.cid) A ,OD

           WHERE CID=OD.COMPID

ORDER BY LV,cid, pid

posted on 2011-08-02 16:45  易成波  阅读(775)  评论(0编辑  收藏  举报