【问题标题】:SQL query to get average sum of other rows and store in current rowsSQL查询以获取其他行的平均总和并存储在当前行中
【发布时间】:2020-12-13 16:50:57
【问题描述】:

我有这样的表,我想查询以存储其他行点的平均值。

USER_ID        POINTS       
------------- --------
 a14e43e4f851  134       
 1e86e5adedbf  40     
 3c66730edf69  149  
 32e24082f97b  67   
 b33e3100a7be  124  
 274ee414ad8f  85   
 bdeef25fc797  172 

例如 - 对于user_id = a14e43e4f851,平均点数总和应该是 avg(40+149+67+124+85+172) 。 PS - 在计算用户 a14e43e4f851 时未计分 (134)。

输出应该是这样的 --

 USER_ID       POINTS   AVG     
-------------  ------- ------
 a14e43e4f851   134     106 which is avg(40+149+67+124+85+172)  
 1e86e5adedbf   40      avg(134+149+67+124+85+172)
 3c66730edf69   149     avg(134+40+67+124+85+172)
 32e24082f97b   67      avg(134+40+149+124+85+172)
 b33e3100a7be   124     ...
 274ee414ad8f   85      ...
 bdeef25fc797   172     ...

【问题讨论】:

  • 如果表中只有一条记录,您期望什么结果?

标签: sql postgresql sql-update average aggregate-functions


【解决方案1】:

您可以使用相关子查询:

select t.*,
    (select avg(t1.points) from mytable t1 where t1.user_id <> t.user_id) as average
from mytable t

另一种使用窗口函数:

select t.*,
    (sum(points) over() - points) / nullif(count(*) - 1, 0) as average
from mytable t

注意:avg 显然与语言关键字冲突,我使用 average 代替。

如果您想要update 声明:

update mytable t
set t.average = (
    select avg(t1.points) from mytable t1 where t1.user_id <> t.user_id
)

但是,我不建议实际存储此值;这是派生信息,可以在需要时使用第一条语句轻松地即时计算。如果您要经常运行查询,您可以创建一个视图:

create view myview as
select t.*,
    (sum(points) over() - points) / nullif(count(*) - 1, 0) as average
from mytable t

【讨论】:

    【解决方案2】:

    我假设 user_id 是 PK。

    WITH q AS (SELECT sum(points) AS s, count(*) AS n FROM mytable)
    UPDATE table SET average = (q.s-points)/(q.n-1);
    

    想法是这样的

    • 所有其他用户得分的平均值是 sum(score)/count(*)

    • 除此之外的所有用户分数的总和等于所有分数的总和减去该用户的分数

    • 除此用户外所有其他用户的得分平均值为 (sum(score)-score_for_this_user)/(count(*)-1)

    好消息是它只需要计算 sum() 和 count() 一次。

    处理表格中只有一行的情况:

    WITH q AS (SELECT sum(points) AS s, NULLIF(count(*),0) AS n FROM mytable)
    UPDATE table SET average = (q.s-points)/(q.n-1);
    

    这使得计数为 NULL 而不是 0,因此更新的平均值也应该为 NULL。

    【讨论】:

    • 你应该处理表中只有一条记录的情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-21
    相关资源
    最近更新 更多