将指标添加到顶部和底部 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
我正在尝试获取 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