2017-06-15 1 views
0

J'essaye de capturer la moyenne de FIRST_CONTACT_CAL_DAYS mais ce que je voudrais faire est de créer un indicateur pour les 10% supérieurs et inférieurs de valeurs afin que je puisse exclure ceux (outliers) de mon calcul moyen.Ajouter un indicateur en haut et en bas 10%

Vous ne savez pas comment procéder, pensez-vous?

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 

Répondre

1

Vous recherchez peut-être quelque chose comme ceci. S'il vous plaît adapter à votre situation. Je suppose que vous pouvez avoir plus d'un «groupe» ou «partition» et vous devez calculer la moyenne pour chaque groupe séparément, après avoir jeté les valeurs aberrantes dans chaque partition. (Une alternative, qui peut être facilement adaptée en adaptant la requête ci-dessous, est de rejeter les valeurs aberrantes au niveau global, et ensuite de grouper et de prendre la moyenne pour chaque groupe.)

Si vous n'avez pas tous les groupes, et tout est un gros tas de données, c'est encore plus facile - vous n'avez pas besoin de GROUP BY et PARTITION BY. Ensuite: la fonction NTILE attribue un numéro de compartiment, dans cet exemple entre 1 et 10, à chaque ligne, en fonction de l'endroit où ils tombent (premier décile, c'est-à-dire premier 10%, décile suivant, ... jusqu'à le dernier décile). Je fais cela dans une sous-requête. Ensuite, dans la requête externe, filtrez le premier et le dernier compartiment avant de vous grouper et vous calculez la moyenne. À des fins de test, je crée trois groupes avec 10 000 nombres aléatoires chacun dans une clause WITH - pas besoin de passer du temps sur cette partie du code, puisqu'il ne fait pas partie de la solution (le code SQL pour résoudre votre problème) - c'est juste un truc sale pour créer des données de test à la volée.

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