【问题标题】:Oracle SQL - Counting distinct column combinationsOracle SQL - 计算不同的列组合
【发布时间】:2017-08-16 13:28:12
【问题描述】:

运行 Oracle 12.1。我有一个 Line Items 表。它的结构是固定的,我无法改变它。我需要构建一个仪表板样式的 Line items 表信息页面,以便人们查看他们的销售区域。此人可能是拥有大片区域的 GVP,也可能是经理或个人代表。 Line Items 表非常不规范化,因为此副本是 DW 的一部分。该表的“副本”仅每 2 周更新一次,看起来像这样。

Line_Item_ID // PK
Account_ID // 
Company_Name // The legal name of the Headquarters
LOB_Name  // Line of business, aka Division within the Company_Name
Account_Type // One of 2 values, ‘NAMED’ or “GENERAL’
ADG_STATUS // 3 possible values, ‘A’, ‘D’ or ‘G’
Industry  // One of 15 values, for this example assume it is ONLY ‘MFG’, ‘GOV’, ‘HEALTHCARE’
 // Now have the sales hierarchy of the rep who sold this
GVP // Group Vice President
SVP // Sales Vice President
RVP // Regional Vice President
RM // Regional Manager
REP // Sales Rep
 // Now have information about the product sold
ProductName
ProductPrice
VariousOtherFields….

我需要制作一个汇总表,用于快速访问仪表板。它将有各种组合的计数,每个人将有一行,而不是帐户。一个人是在任何 GVP、SVP、RVP、RM 或 REP 字段中列出的每个唯一的人。这是最终结果表的样子。除了 PERSON 之外,每一列都基于一个 DISTINCT 计数,并且是一个整数值。

PERSON
TOTAL_COMPANIES // For this person, count of DISTINCT COMPANY_NAME
TOTAL_LOBS // For this person, count of DISTINCT LOBS
TOTAL_COMPANIES_NAMED // count of DISTINCT COMPANY_NAME with ACCOUNT_TYPE=’NAMED’
TOTAL_COMPANIES_GENERAL // count of DISTINCT COMPANY_NAME with ACCOUNT_TYPE=’GENERAL’
TOTAL_LOBS_NAMED  // count of DISTINCT LOB_NAME with ACCOUNT_TYPE=’NAMED’
TOTAL_LOBS_GENERAL // count of DISTINCT LOB_NAME with ACCOUNT_TYPE=’GENERAL’
TOTAL_COMPANIES_STATUS_A // count of DISTINCT COMPANY_NAME with ADG_STATUS=’A’
TOTAL_COMPANIES_STATUS_D // count of DISTINCT COMPANY_NAME with ADG_STATUS=’D’
TOTAL_COMPANIES_STATUS_G // count of DISTINCT COMPANY_NAME with ADG_STATUS=’G’
TOTAL_LOB_STATUS_A  // count of DISTINCT  LOB_NAME with ADG_STATUS=’A’
TOTAL_LOB_STATUS_D // count of DISTINCT  LOB_NAME with ADG_STATUS=’D’
TOTAL_LOB_STATUS_G // count of DISTINCT  LOB_NAME with ADG_STATUS=’G’
//Now Various Industry Permutations.  I have 15 different industries, but only showing 2.  This will only be at the COMPANY_NAME level, not the LOB_NAME level
MFG_COMPANIES_STATUS_A // count of DISTINCT COMPANY_NAME with ADG_STATUS=’A’ and Industry = ‘MFG’
MFG_COMPANIES_STATUS_D // count of DISTINCT COMPANY_NAME with ADG_STATUS=’D’ and Industry = ‘MFG’
MFG_COMPANIES_STATUS_G // count of DISTINCT COMPANY_NAME with ADG_STATUS=’G’ and Industry = ‘MFG’

GOV_COMPANIES_STATUS_A // count of DISTINCT COMPANY_NAME with ADG_STATUS=’A’ and Industry = ‘GOV’
GOV_COMPANIES_STATUS_D // count of DISTINCT COMPANY_NAME with ADG_STATUS=’D’ and Industry = ‘GOV’
GOV_COMPANIES_STATUS_G // count of DISTINCT COMPANY_NAME with ADG_STATUS=’G’ and Industry = ‘GOV’

大约有。订单项表中有 400 人、35000 个唯一帐户和 200,000 个条目。

那么我的策略是什么?我考虑过制作另一个独特的 PERSON 值表,并将其用作驾驶表。我们将此表称为 PERSON_LIST。

Pseudo-code…

For each entry in PERSON_LIST
   For all LINE_ITEMS where person_list in ANY(GVP, SVP, RVP, RM, REP) do
      Calculations…

这将是一个非常漫长的运行过程……

我怎样才能更有效地做到这一点(基于设置而不是逐行)?我相信我必须对 INDUSTRY 列表使用 PIVOT 运算符,但我可以使用 PIVOT 和附加条件吗? Aka 计数具有特定行业和特定 ADG_STATUS 的不同 COMPANY?

最受赞赏的任何想法或 SQL 代码。

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    您可以unpivot原始数据以将原始 GVP 等列中的数据放入一个“人”列:

    select * from line_items
    unpivot (person for  role in (gvp as 'GVP', svp as 'SVP', rvp as 'RVP',
      rm as 'RM', rep as 'REP'))
    

    然后将其用作 CTE 或内联视图,与您展示的内容差不多;使用 case 表达式进行条件聚合,例如:

    select person,
      count(distinct company_name) as total_companies,
      count(distinct lob_name) as total_lobs,
      count(distinct case when account_type='NAMED' then company_name end)
        as total_companies_named,
      count(distinct case when account_type='GENERAL' then company_name end)
        as total_companies_general,
      count(distinct case when account_type='NAMED' then lob_name end)
        as total_lobs_named,
      count(distinct case when account_type='GENERAL' then lob_name end)
        as total_lobs_general,
      count(distinct case when adg_status='A' then company_name end)
        as total_companies_status_a,
      count(distinct case when adg_status='D' then company_name end)
        as total_companies_status_d,
      count(distinct case when adg_status='G' then company_name end)
        as total_companies_status_g,
      count(distinct case when adg_status='A' then lob_name end)
        as total_lob_status_a,
      count(distinct case when adg_status='D' then lob_name end)
        as total_lob_status_d,
      count(distinct case when adg_status='G' then lob_name end)
        as total_lob_status_g,
      count(distinct case when adg_status='A' and industry = 'MFG' then company_name end)
        as mfg_companies_status_a,
      count(distinct case when adg_status='D' and industry = 'MFG' then company_name end)
        as mfg_companies_status_d,
      count(distinct case when adg_status='G' and industry = 'MFG' then company_name end)
        as mfg_companies_status_g,
      count(distinct case when adg_status='A' and industry = 'GOV' then company_name end)
        as gov_companies_status_a,
      count(distinct case when adg_status='D' and industry = 'GOV' then company_name end)
        as gov_companies_status_d,
     count(distinct case when adg_status='G' and industry = 'GOV' then company_name end)
        as gov_companies_status_g
    from (
      select * from line_items
      unpivot (person for  role in (gvp as 'GVP', svp as 'SVP', rvp as 'RVP',
        rm as 'RM', rep as 'REP'))
    )
    group by person;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      相关资源
      最近更新 更多