将指标添加到顶部和底部 10%

Add indicator to top and bottom 10%

我正在尝试获取 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

您可能正在寻找这样的东西。请根据您的情况进行调整。

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

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

然后:函数 NTILE 根据它们落在的位置(第一个十分位数,即前 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