SQL Server: weighted average + GROUP BY

13,299

Assuming you want Weighed Avg Margin ...

Select
       ...
       sum(amount*margin)/sum(amount) as 'Weighted Avg'
       ...
 From  ...
 Group By ...

Edit - To avoid the dreaded Divide-By-Zero

case when sum(amount)=0 then null else sum(amount*margin)/sum(amount) end as 'Weighted Avg'

Edit 2 - NullIf()

...
sum(amount*margin)/NullIf(sum(amount),0) as 'Weighted Avg'
...
Share:
13,299
Harper
Author by

Harper

Updated on July 28, 2022

Comments

  • Harper
    Harper almost 2 years

    I am trying to calculate a weighted average in SQL Server. I'm aware that there are tons of questions out there addressing the problem, but I have the additional problem that I query a lot of other columns with a GROUP BY and aggregate functions like sum() and avg().

    Here is my query:

    SELECT 
        AVG(tauftr.kalkek) AS 'PurchPrice',
        SUM(tauftr.amount) AS 'Amount',
        AVG(tauftr.price) AS 'SellingPrice',
        tauftr.product AS 'Product',
        auftrkopf.ins_usr AS 'Seller',
        DATEPART(wk, auftrkopf.date) AS 'Week',
        AVG([margin]) AS 'Margin' /* <--- THIS IS WRONG  */ 
        /* CALCULATE HERE: WEIGHTED AVERAGE BETWEEN 'amount' and 'margin' */
    FROM 
        [tauftr] AS tauftr
    JOIN
        tauftrkopf AS auftrkopf ON tauftr.linktauftrkopf = auftrkopf.kopfnr
    WHERE
        auftrkopf.[status] = 'L'
        AND auftrkopf.typ = 'B'
        AND auftrkopf.date >= '01.03.2017'
        AND auftrkopf.ins_usr ='HS'
    GROUP BY
        tauftr.product, auftrkopf.ins_usr, DATEPART(wk,auftrkopf.date)
    

    I suppose it could be possible to use a INNER JOIN with exactly the same WHERE clause, but I don't want to execute the query two times. And I don't know ON what field to JOIN...

    Is it possible without creating a table? (I do not have write permissions)

  • SqlZim
    SqlZim over 7 years
    Nice one! I was stuck trying to figure out which one he wanted to use as the weight.
  • John Cappelletti
    John Cappelletti over 7 years
    @SqlZim Jury is still out, OP may be looking for the total WAM.
  • John Cappelletti
    John Cappelletti over 7 years
    @Harper I suspect you were just over-thinking it. Happens to us all :)
  • Harper
    Harper over 7 years
    Oh, nice, thanks for the update. DIV/0 is a real danger in this.
  • John Cappelletti
    John Cappelletti over 7 years
    @Harper Happy it helped