Reputation: 11479
I have a table
| Location | Unit | ...
+----------|------+----
| A | 1 | ...
| A | 1 | ...
| B | 1 | ...
| A | 2 | ...
| C | 2 | ...
| ... | ... | ...
and I want to compute a new table with the 'average' location value for each unit, in the following sense:
| Location | Unit | Weight |
+----------|------+--------+
| A | 1 | 0.6667 |
| B | 1 | 0.3333 |
| A | 2 | 0.5 |
| C | 2 | 0.5 |
| ... | ... | ... |
Of course it is simple enough to get the totals
select unit, location, count(*)
from table1
group by unit, location;
and to create the table
create table table2 (Unit nvarchar(50), Location int, Weight float);
but I'm not sure how to populate it with the average data. (This isn't hard, but somehow I'm stuck... it's been many years since I worked on SQL Server.)
Upvotes: 2
Views: 72
Reputation: 94859
You'd use COUNT OVER
for this:
select distinct
location, unit,
cast(count(*) over (partition by unit, location) as decimal) /
cast(count(*) over (partition by unit) as decimal) as weight
from mytable
order by unit, location;
Upvotes: 5
Reputation: 1269503
You want to do a weighted average, with units as the weight. You need both the sum for each location/unit combination and the total for each location
. To produce your output:
select location, unit, (1.0*unit) / sum(unit) over (partition by location)
from table1
group by location, unit;
The 1.0*
is just a fast way of converting to a decimal value, in the event that unit
is actually an integer.
EDIT:
If you just want the counts, then this should work:
select location, unit, count(*) as cnt,
(1.0*count(*)) / sum(count(*)) over (partition by unit)
from table1
group by location, unit;
Upvotes: 2
Reputation: 938
While you haven't said that there is a weight column, I'm assuming there must be (otherwise, what do you mean by weight?)
select unit, location, AVG(weight)
from table1
group by unit, location;
as the select statement
select unit, location, AVG(weight)
into table2
from table1
group by unit, location;
as an insert into a new table
Upvotes: 0