2013-06-14 17 views
7

Ho un set di dati che include PREZZO, SUBTYPE e altri. Voglio fare qualche rimozione anomala prima di usare il set di dati. Voglio rimuovere le righe per le cose in cui il prezzo è ridicolmente alto o basso, in ogni SUBTYPE.Come filtro l'1% superiore e l'1% inferiore di dati in ciascun gruppo in SQL

Per ogni SUBTYPE guarda l'intervallo dei PREZZI e rimuovi o filtra le righe. Mantieni le file tra: PRICErange * .01 | KEEP | PRICErange * .99

Questo mi è stato fornito da Martin Smith su StackOverflow, ho modificato questa domanda, quindi partiamo da qui.

;WITH CTE  
AS (SELECT *,     
ROW_NUMBER() OVER (PARTITION BY SUBTYPE ORDER BY PRICE) AS RN,      
COUNT(*) OVER(PARTITION BY SUBTYPE) AS Cnt    
FROM all_resale)  
SELECT *  
FROM CTE  
WHERE (CASE WHEN Cnt > 1 THEN 100.0 * (RN -1)/(Cnt -1) END) BETWEEN 1 AND 99 

Non sono sicuro che sia ciò che devo fare. Non so quante file verranno rimosse dalle estremità.

+3

Quando dici "Rimuovi" intendi filtro o cancella? – KingCronus

+1

Anche "L'1% più alto del PREZZO ordinato" è ambiguo: vuoi ridurre il numero di record dell'1%? –

+0

Filtro. Mi piacerebbe che restasse nel set di dati, ma non comparire in questa query. Sto provando a fare qualche controllo anomalo, ma posso anche tornare indietro e ripetere il processo con i valori anomali. D'altra parte, se l'output è stato inserito in una nuova tabella, potrebbe essere eliminato completamente nella nuova tabella. –

risposta

5

Non si specifica esattamente come si definisce l'1 percento e come devono essere gestiti i legami.

Un modo è quello di sotto

;WITH CTE 
    AS (SELECT *, 
       ROW_NUMBER() OVER (PARTITION BY SUBTYPE ORDER BY PRICE) AS RN, 
       COUNT(*) OVER(PARTITION BY SUBTYPE) AS Cnt 
     FROM all_resale) 
SELECT * 
FROM CTE 
WHERE (CASE WHEN Cnt > 1 THEN 100.0 * (RN -1)/(Cnt -1) END) BETWEEN 1 AND 99 

che assume l'elemento prezzo più alto è 100%, il prezzo più basso 0% e tutti gli altri in scala in modo uniforme tra non tenendo conto dei legami. Se è necessario per tener conto dei legami guardare in RANK piuttosto che ROW_NUMBER

NB: Se tutti i sottotipi hanno una quantità relativamente grande di righe si potrebbe usare NTILE(100) invece, ma non distribuisce tra secchi e se il numero di righe è piccolo rispetto al numero di secchi.

Problemi correlati