Oracle - 相邻的层次数据汇总

时间:2017-09-02 01:50:36

标签: sql oracle hierarchy

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

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');

这将返回Mgr-A,Mgr-B和Mgr-C的领土ID。我的问题是如何汇总Mgr-A,Mgr-B和Mgr-C下每个人的销售渠道?

这是我到目前为止所做的,但没有考虑到Mgr-A,Mgr-B和Mgr-C是组织树的一部分,而它们下面的数据需要是&# 34;卷起"。

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
...

1 个答案:

答案 0 :(得分:1)

您需要创建一个内联视图(子查询),显示所有对等项及其下的子树。然后将此视图加入ALL_DEAL表,并按原样执行所有聚合;您还希望按PEER分组。

为了说明如何创建我之前提到的内联视图,我将使用标准EMP模式中的SCOTT表。假设我想为员工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