2017-09-02 125 views
0

Oracle 12c R1 - 我正在尝试为销售组织构建仪表板。具体来说,它用于销售预测(也称为销售管道)。涉及两个表,名为IB_HIERARCHY_S的代表层次结构表和名为ALL_DEAL的销售预测表。Oracle - 层级数据的相邻汇总

IB_HIERARCHY_S表与Oracle附带的传统EMP表非常相似...代表具有员工ID,代表具有领土ID,领土ID汇总至其管理者的领土ID。在销售层次结构中,每人一行,上下导航层次的方式是TERRITORY_ID = PARENT_TERRITORY_ID。它包括整个销售组织,从最低的代表到经理直到组织副总裁。这个层次结构大约有6层深化。

IB_HIERARCHY_S structure 

TERRITORY_ID - primary key 
EMAIL_ADDRESS – email address of the rep 
PAR_TERR_ID – parent territory ID, aka the territory ID of this person’s manager 
… 

另一个表是ALL_DEAL。这是一个销售预测表。每个销售机会在此表中都有一行。

ALL_DEAL structure 

FIELD_REP_E_MAIL – email address of the rep. 
TERRITORY_ID – Territory ID of the rep who is forecasting the deal 
FISCAL_QUARTER – the quarter the deal is expected to close 
TERRITORY_LOB – The line of business who is actively working the deal, Field rep of Telesales Rep 
REV_TYPE – One of 6 buckets for the revenue 
PIPE – a forecast dollar amount 

该问题与显示/比较树的多个部分相互作用有关。显示一个代表如何做的很容易......显示代表如何对付他的同龄人是一个更具挑战性的问题。真正的问题是比较彼此不在代表级别的对方,因为您必须“汇总”和层次结构中其下的每个人的PIPE。假设VP有3个直接报告,'Mgr-A','Mgr-B'和'Mgr-C'。有人使用这个仪表板将输入'Mgr-A'的电子邮件地址,并希望看到这位经理与'Mgr-B'和'Mgr-C'的比较。我们需要找到Mgr-A的同行,然后为所有同行汇总层次结构中他们下面的每个人的数据。

我能找到同伴与此SQL

SELECT TERRITORY_ID 
     FROM IB_HIERARCHY_S 
where par_terr_id in 
(select par_terr_id FROM IB_HIERARCHY_S 
    where email_address = 'Mgr-A'); 

这将返回经理-A,MGR-B和经理-C境内ID。我的问题是如何汇总Mgr-A,Mgr-B和Mgr-C下各个销售渠道?

这是我到目前为止的内容,但没有考虑到Mgr-A,Mgr-B和Mgr-C是组织结构的一部分,并且它们下面的数据需要“卷起来”。

with peer_list as 
(SELECT TERRITORY_ID 
     FROM IB_HIERARCHY_S 
where par_terr_id in (select par_terr_id FROM IB_HIERARCHY_S where email_address = 'Mgr-A') 
) 
select territory_id, fiscal_quarter, territory_lob, rev_type, sum(pipe) as PIPE, 
grouping(field_rep_e_mail) as grp_email, 
grouping(fiscal_quarter) as grp_1, 
grouping(territory_lob) as grp_2, 
grouping(rev_type) as grp_3 
from smb.all_deal 
where fiscal_quarter = 'FY18-Q2' 
and TERRITORY_ID in (select territory_ID from peer_list) 
group by rollup(territory_id, fiscal_quarter, territory_lob, rev_type) 
order by territory_id, fiscal_quarter, territory_lob, rev_type; 

任何帮助或想法赞赏。

ANSWER

什么最后的工作是识别(通过CONNECT BY查询),所有的根和叶全部电子邮件。然后,我总结了叶邮件中的ALL_DEAL,但通过根邮件分组。

with peer_list as 
(SELECT distinct email_address,    
     REGEXP_SUBSTR (SYS_CONNECT_BY_PATH(territory_id, '/'), '[^/]+', 1, 1) Root_Terr_Id, 
     REGEXP_SUBSTR (SYS_CONNECT_BY_PATH(email_address, '/'), '[^/]+', 1, 1) Root_Email 
     FROM IB_HIERARCHY_S 
     START WITH territory_id in 
(SELECT TERRITORY_ID 
     FROM IB_HIERARCHY_S 
     where par_terr_id in 
     (select par_terr_id FROM IB_HIERARCHY_S 
     where email_address = 'Mrg-A')) 
     CONNECT BY PRIOR territory_id = par_terr_id 
order by email_address 
) 
select <data> from ALL_DEAL, PEER_LIST 
... 
+0

请创建[最小,完整,可验证的示例](https://stackoverflow.com/help/mcve)。 – krokodilko

回答

1

您需要创建一个内联视图(子查询),显示所有对等和它们下面的子树。然后,您将该视图加入ALL_DEAL表中,并且您已经完成了所有聚合;你也可以通过PEER进行分组。

为了说明如何创建前面提到的内联视图,我将使用标准SCOTT模式中的EMP表。假设我想为员工7566创建视图(这可以是硬编码的,也可以是一个绑定变量;或者,您可以为每个人创建一个表,并只进行一次所有计算,从中创建一个物化视图,任何进一步的比较和分析都会读取这个大型MV的数据。)

因此:员工7566.我该如何与这位员工和他的同事一起获得一张表,并向每位同行展示所有员工?这是如何。使用connect_by_root分层查询的伪列。

select connect_by_root(empno) as peer, empno 
from emp 
connect by mgr = prior empno 
start with empno in (select empno 
         from emp 
         where mgr = (select mgr from emp where empno = 7566) 
        ) 
; 

PEER EMPNO 
---- ---- 
7566 7566 
7566 7788 
7566 7876 
7566 7902 
7566 7369 
7698 7698 
7698 7499 
7698 7521 
7698 7654 
7698 7844 
7698 7900 
7782 7782 
7782 7934 
在表中的数据以及这些数据预期resutl的
+0

这足够接近我得到我需要的地方....最终工作的是在层次结构表中根据组进行求和(叶)。我将在我的原始问题中添加SQL以供其他人查看... – user1009073