2017-06-15 114 views
0

我試圖捕獲FIRST_CONTACT_CAL_DAYS的平均值,但是我想要做的是爲值的頂部和底部10%創建一個指標,以便我可以將這些(異常值)從我的平均計算。將指標添加到頂部和底部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 

回答

1

您可能正在尋找類似的東西。請適應你的情況。

我假設你可能有多個「組」或「分區」,並且需要在每個分區中拋出異常值後分別計算每個組的平均值。 (通過調整下面的查詢,可以很容易地解決這個問題的另一種方法,就是在全球範圍內排除異常值,然後才能將每個羣組的平均值進行分組並取得平均值。)

如果您還沒有任何組,所有事情都是一大堆數據,它更簡單 - 您不需要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 
相關問題