【问题标题】:Add indicator to top and bottom 10%将指标添加到顶部和底部 10%
【发布时间】:2017-06-15 15:33:04
【问题描述】:

我正在尝试获取 FIRST_CONTACT_CAL_DAYS 的平均值,但我想做的是为顶部和底部 10% 的值创建一个指标,以便我可以从我的平均计算中排除这些(异常值)。

不知道该怎么做,有什么想法吗?

SELECT DISTINCT 
        TO_CHAR(A.FIRST_ASSGN_DT,'DAY') AS DAY_NUMBER,
        A.FIRST_ASSGN_DT,
        A.FIRST_CONTACT_DT,
        TO_CHAR(A.FIRST_CONTACT_DT,'DAY') AS DAY_NUMBER2,                   
        A.FIRST_CONTACT_DT AS FIRST_PHONE_CONTACT, 
        A.ID,
        ABS(TO_DATE(A.FIRST_CONTACT_DT, 'DD/MM/YYYY') - TO_DATE(A.FIRST_ASSGN_DT, 'DD/MM/YYYY')) AS FIRST_CONTACT_CAL_DAYS,   

        FROM HIST A
          LEFT JOIN  CONTACTS D ON A.ID = D.ID 

        WHERE 1=1

【问题讨论】:

    标签: oracle outliers case-statement


    【解决方案1】:

    您可能正在寻找类似的东西。请适应你的情况。

    我假设您可能有多个“组”或“分区”,并且在剔除每个分区中的异常值之后,您需要分别计算每个组的平均值。 (通过调整下面的查询可以轻松适应的另一种方法是在全局级别丢弃异常值,然后才对每个组进行分组并取平均值。)

    如果您没有任何组,并且所有内容都是一大堆数据,那就更容易了 - 您不需要 GROUP BY 和 PARTITION BY。

    然后:函数 NTILE 为每一行分配一个桶号,在这个例子中,在 1 到 10 之间,基于它们所在的位置(第一个十分位,即前 10%,下一个十分位,...一直到最后十分位)。我在子查询中执行此操作。然后在外部查询中,在分组之前过滤掉第一个和最后一个桶,然后计算平均值。

    出于测试目的,我在 WITH 子句中创建了三个组,每个组包含 10,000 个随机数 - 无需在该部分代码上花费任何时间,因为它不是解决方案的一部分(用于解决问题的 SQL 代码) - 动态创建测试数据只是一个肮脏的技巧。

    with
         inputs ( grp, val ) as (
           select     ceil(level/10000), dbms_random.value(0, 150)
           from       dual
           connect by level <= 30000
         )
    select   grp, avg(val) as avg_val
    from     (
               select grp, val, ntile(10) over (partition by grp order by val) as bkt
               from   inputs
             )
    where    bkt between 2 and 9
    group by grp
    ;
    
    GRP                  AVG_VAL
    ---  -----------------------
      1 75.021614866547043734458
      2 74.286117923344418598032
      3 75.437412573353736953791
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-30
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      • 2020-04-27
      • 2017-12-28
      • 1970-01-01
      • 2020-02-05
      相关资源
      最近更新 更多