![](/img/trans.png)
[英]How to add a new column in SQL db with grouped average of another column? (PostgreSQL)
[英]SQL - how to add column with average value, grouped
本质上,我从TABLE_A开始
France - 100
France - 200
France - 300
Mexico - 50
Mexico - 50
Mexico - 56
Poland - 100
Poland - 150
最后,我想添加一列,其中包含按国家/地区划分的平均值。
France - 100 - 200
France - 200 - 200
France - 300 - 200
Mexico - 500 - 520
Mexico - 500 - 520
Mexico - 560 - 520
Poland - 100 - 125
Poland - 150 - 125
我想通过更新/更改TABLE_A并在可能的情况下不创建新表来做到这一点。 我在甲骨文工作。 感谢您的任何想法!
您可以使用avg() over()
。 我看不到存储这些计算列的原因。 每次添加新行或更新表中的行时,都必须更新它们。
select t.*, avg(val) over(partition by country) average
from yourtable t
要将其添加为列,请执行以下操作:
alter yourtable add average number(10,2);
commit;
update yourtable t
set t.average = (select avg(val)
from yourtable
where country = t.country)
;
commit;
简短的答案是:不要那样做。 您正在破坏数据库的规范化,而这可以通过函数来完成。 在Oracle中进行此操作时,可以使用RESULT CACHE子句编写函数,例如
FUNCTION average_by_country (country_id IN countries.id%TYPE)
RETURN countries.whatever%TYPE
RESULT_CACHE RELIES_ON (countries)
IS
等等,这将为每个国家/地区缓存结果,从而使功能评估非常快。
然后,您可以使用
SELECT country_id, country_name, country_data, average_by_country(country_id)
FROM countries WHERE etc etc
declare
cursor c_records is
select movie_id, count(*) cnt, avg(rating) avgr
from ratings
group by movie_id;
l_i number := 0;
begin
for l_rec in c_records loop
update movies
set avg_user_rating = l_rec.avgr,
rating_count = l_rec.cnt
where movie_id = l_rec.movie_id;
l_i := l_i + 1;
if mod(l_i, 1000) = 0 then
commit;
end if;
end loop;
end;
花了9秒,而
update movies m
set avg_user_rating =
(
select avg(r.rating)
from ratings r
where r.movie_id = m.movie_id
)
9小时后被取消,因为它仍未完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.