【问题标题】:Oracle - Adjacent Rollup of Hierarchial DataOracle - 分层数据的相邻汇总
【发布时间】:2017-09-02 01:50:36
【问题描述】:

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 是组织树的一部分,并且它们下面的数据需要“滚动”向上”。

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;

任何帮助或想法表示赞赏。

回答

最终的工作是识别(通过 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
...

【问题讨论】:

标签: sql oracle hierarchy


【解决方案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

【讨论】:

  • 这已经足够接近我需要去的地方了......最终的工作是在层次结构表中按组按组求和(叶)。我将在我原来的问题中添加 SQL 以供其他人查看...
猜你喜欢
  • 1970-01-01
  • 2021-12-25
  • 2020-08-24
  • 2014-10-05
  • 2020-07-13
  • 1970-01-01
  • 1970-01-01
  • 2017-12-20
  • 1970-01-01
相关资源
最近更新 更多