有没有办法在不使用子查询的情况下根据不同的行计算平均值?

Posted

技术标签:

【中文标题】有没有办法在不使用子查询的情况下根据不同的行计算平均值?【英文标题】:Is there a way to calculate average based on distinct rows without using a subquery? 【发布时间】:2021-10-12 07:27:12 【问题描述】:

如果我有这样的数据:

+----+-------+
| id | value |
+----+-------+
|  1 |    10 |
|  1 |    10 |
|  2 |    20 |
|  3 |    30 |
|  2 |    20 |
+----+-------+

如何在不使用子查询的情况下根据不同的 id 计算平均值(即直接查询表)?

对于上面的示例,它将是 (10+20+30)/3 = 20

我尝试执行以下操作:

SELECT AVG(IF(id = LAG(id) OVER (ORDER BY id), NULL, value)) AS avg
FROM table

基本上我在想,如果我按 id 排序并检查前一行以查看它是否具有相同的 id,则该值应该为 NULL,因此它不会计入计算中,但不幸的是我不能把聚合函数中的分析函数。

【问题讨论】:

有什么理由不想使用子查询? 外层查询会有其他参数需要访问表中的所有数据 @User 你真的应该问你关心的实际问题。 这个与outer query 相关的问题是您不应隐瞒的问题。解释真正的问题。让我们看看其他人是否有以前没有考虑过的建议。例如:某些数据库可以按照您的要求执行。 :) 首先,请标记您的 DBMS 和版本 【参考方案1】:

据我所知,如果没有子查询,您将无法做到这一点。我会使用:

SELECT AVG(avg_value)
FROM
(
    SELECT AVG(value) AS avg_value
    FROM yourTable
    GROUP BY id
) t;

【讨论】:

【参考方案2】:
WITH RANK AS (

Select *,
ROW_NUMBER() OVER(PARTITION BY ID) AS RANK

FROM 
TABLE
QUALIFY RANK = 1
)

SELECT 
AVG(VALUES)
FROM RANK

【讨论】:

【参考方案3】:

外部查询会有其他参数需要访问表中的所有数据

我将此评论解释为希望对每一行进行平均,而不是进行汇总。如果是这样,您可以使用窗口函数:

select t.*,
       avg(case when seqnum = 1 then value end) over () as overall_avg
from (select t.*,
             row_number() over (partition by id order by id) as seqnum
      from t
     ) t;

【讨论】:

【参考方案4】:

是的,有办法, 只需在 avg 函数中使用 distinct ,如下所示:

select avg(distinct value) from tab;

http://sqlfiddle.com/#!4/9d156/2/0

【讨论】:

OP 想要不同的 ID,而不是值。 考虑两个具有相同值的不同 ID。 @Serg 你说得对,我没看清楚问题

以上是关于有没有办法在不使用子查询的情况下根据不同的行计算平均值?的主要内容,如果未能解决你的问题,请参考以下文章

在不使用子查询的情况下使用 SELECT DISTINCT ON 计算总行数

如何在不使用pivot和unpivot的情况下在SQL Server中水平显示数据?

使用 querySelectorAll 时,有没有办法在不使用 ID 的情况下引用上下文节点的直接子节点?

如何在不使用循环的情况下更新 SQL Server 中两组不同条件之间的行

有没有办法在不进行查询的情况下读取指针

有没有办法在不使用子项的情况下使 Firebase 搜索查询不区分大小写? [复制]