2011-01-19 8 views
10

Ho una tabella in Oracle con più righe per una determinata parte. Ogni riga ha una quantità e un prezzo associato ad essa. C'è anche una quantità totale che l'insieme di righe per una determinata parte si somma a. Di seguito è riportato un esempio dei dati. Quello di cui ho bisogno è ottenere il prezzo medio ponderato per la parte. Per esempio, se una quantità di 100 di una parte ha un prezzo di 1 e una quantità di 50 ha un prezzo di 2 prezzo medio ponderato è 1.33333333Query per trovare un prezzo medio ponderato

PART TOTAL_QTY QTY PRICE_PER 
---------------------------------- 
part1 317  244 27 
part1 317  40 53.85 
part1 317  33 24.15 

Idea?

risposta

16

Prova questo:

SELECT part, SUM(qty*price_per)/SUM(qty) 
    FROM <YOUR_TABLE> 
GROUP BY part 
+0

Immagino che non è necessario il campo TOTAL_QTY più. È palesemente contrario al principio dei dati di unicità: ogni dato deve apparire solo una volta. – Josep

0

creare un utente definito funzione di aggregazione per calcolare la media ponderata:

CREATE OR REPLACE TYPE WEIGHTED_AVG_O AS OBJECT ( 
    sum_of_weights NUMBER, 
    sum_of_weights_times_value NUMBER, 

    STATIC FUNCTION ODCIAGGREGATEINITIALIZE(cs_ctx IN OUT WEIGHTED_AVG_O) RETURN NUMBER, 
    MEMBER FUNCTION ODCIAGGREGATEITERATE (self IN OUT WEIGHTED_AVG_O, value IN WEIGHTED_AVG_O) RETURN NUMBER, 
    MEMBER FUNCTION ODCIAGGREGATEMERGE  (self IN OUT WEIGHTED_AVG_O, ctx2 IN OUT WEIGHTED_AVG_O) RETURN NUMBER, 
    MEMBER FUNCTION ODCIAGGREGATETERMINATE (self IN OUT WEIGHTED_AVG_O, returnvalue OUT NUMBER, flags IN NUMBER) RETURN NUMBER 
); 
/



CREATE OR REPLACE TYPE BODY WEIGHTED_AVG_O 
AS 

    STATIC FUNCTION ODCIAGGREGATEINITIALIZE(cs_ctx IN OUT WEIGHTED_AVG_O) RETURN NUMBER 
    IS 
    BEGIN 
    cs_ctx := WEIGHTED_AVG_O(0, 0); 
    RETURN odciconst.success; 
    END; 

    MEMBER FUNCTION ODCIAGGREGATEITERATE (self IN OUT WEIGHTED_AVG_O, value IN WEIGHTED_AVG_O) RETURN NUMBER 
    IS 
    BEGIN 
    self.sum_of_weights := self.sum_of_weights + value.sum_of_weights; 
    self.sum_of_weights_times_value := self.sum_of_weights_times_value + value.sum_of_weights * value.sum_of_weights_times_value; 
    RETURN odciconst.success; 
    END; 

    MEMBER FUNCTION ODCIAGGREGATEMERGE  (self IN OUT WEIGHTED_AVG_O, ctx2 IN OUT WEIGHTED_AVG_O) RETURN NUMBER 
    IS 
    BEGIN 
    RETURN odciconst.success; 
    END; 

    MEMBER FUNCTION ODCIAGGREGATETERMINATE (self IN OUT WEIGHTED_AVG_O, returnvalue OUT NUMBER, flags IN NUMBER) RETURN NUMBER 
    IS 
    BEGIN  
    IF sum_of_weights = 0 THEN 
     returnvalue := NULL; 
    ELSE 
     returnvalue := sum_of_weights_times_value/sum_of_weights; 
    END IF; 
    RETURN odciconst.success; 
    END; 

END; 
/


CREATE OR REPLACE FUNCTION WEIGHTED_AVG (input WEIGHTED_AVG_O) 
    RETURN NUMBER PARALLEL_ENABLE 
    AGGREGATE USING WEIGHTED_AVG_O; 
/

query con i tuoi dati:

SELECT part, WEIGHTED_AVG(WEIGHTED_AVG_O(qty, price_per)) 
    FROM <YOUR_TABLE> 
GROUP BY part; 
Problemi correlati