3

This is done in Microsoft SQL Server 2008 R2.

I'll start out with an example table.

Organization | MoneyAmount | MoneyAmountAvg

ISD          | 500         | 
ISD          | 500         | 
ISD          | 500         | 
QWE          | 250         | 
ISD          | 500         | 
QWE          | 250         | 
OLP          | 800         | 
ISD          | 500         | 

I need the MoneyAmountAvg column to have a value of MoneyAmount/(# of times that organization shows up

So for example, the MoneyAmountAvg column for the ISD rows would have a value of 100.

QWE would have 125 for each row in the MoneyAmountAvg column and OLP would have a value of 800 since it is there only once.

This is only an example table. The actual table is much bigger and has more organizations, but it has the same criteria. Some organizations have multiple rows, while others are there only once.

I just need a way for it to count how many times each organization is listed when I use an update statement for that organization's MoneyAmountAvg column. Hard coding it for each organization is definitely not an option since they can change at any moment.

Any help is appreciated.

6 Answers 6

2

Here is my answer:

select organization, moneyamount,
       moneyamount / count(*) over (partition by organization)
from t

This is a simple application of a window function. I think most of the other answers are producing the overall average.

For an update statement, simply do:

 with toupdate as (
    select organization, moneyamount,
           moneyamount / count(*) over (partition by organization) as newval
    from t
 )
 update toupdate
       set MoneyAmountAvg = newval
Sign up to request clarification or add additional context in comments.

4 Comments

The SELECT statement works, however, I need this to work with an UPDATE statement. I know you have to use a CTE, but I'm having a bit of trouble.
Appreciate the help. One last problem. I have another column in there called LoadDt which basically reflects the date that row was inserted. I want it to update the actual table only where: LoadDt = (SELECT MAX(LoadDt) From [TableName]) When I add that where clause either in after the FROM statement or after the SET statement, it tells me 203 rows were affected, however all the rows with the latest LoadDt are still unaffected.
NVM, Figured it out. You forgot to SELECT the MoneyAmountAvg column in your SELECT statement that was inside your UPDATE statement and I accidentally updated the MoneyAmount column instead without noticing.
One last question. Is there anyway to tell it to set the newval expression as a decimal? I'm getting some numbers rounded down when they should be decimals.
2

Try something like this:

;WITH CTE AS
(
    SELECT
        Org, Moneyamount,
        MoneyAvg = AVG(MoneyAmount) OVER(PARTITION BY Org),
        OrgCount = COUNT(*) OVER (PARTITION BY Org)
    FROM 
        dbo.YourTableHere
)
SELECT DISTINCT Org, MoneyAmount, OrgCount, MoneyAvg / OrgCount
FROM CTE

That seems to return what you're looking for:

enter image description here

Comments

0

You can do this using analytic functions:

SELECT  Organization,
        MoneyAmount,
        MoneyAmountAvg = MoneyAmount / COUNT(*) OVER(PARTITION BY Organization)
FROM    T

Example on SQL Fiddle

2 Comments

The question isn't the overall average, just the value in the column divided by the number of times.
@GordonLinoff Thanks, was making the change as you commented having seen the SQL Fiddle gave the wrong result.
0
SELECT (MIN(MoneyAmount) / COUNT(*)) AS AvgMoneyAmount
FROM your_table
GROUP BY Organization

This works if MoneyAmout for a single Organization is always equal.


But I'd say: Refactor the table:

Organization | MoneyAmount | count
----------------------------------
ISD          | 500         | 5
QWE          | 250         | 2
... 

Comments

0
select example.Organization, example.MoneyAmount,
       example.MoneyAmount / count(group_table.Organization) as  MoneyAmountAvg
from example
  inner join example group_table
     on example.Organization = group_table.Organization

Comments

0
select
    organization
    ,avg(MoneyAmount) / count(1) 
  from tab
  group by organization

The purpouse of avg(Moneyamount) is to handle possible different values of amount for the same organization.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.