SQL从连接列中计算出平均值

时间:2016-08-07 18:30:44

标签: sql oracle

我需要显示3列,我需要加入另一个从CLUB_FEE列计算AVG的列。我的代码不起作用,它抛出“不是单组的群组功能”有人可以帮忙吗?这是我的SQL:

SELECT S.MEMBER_ID, S.CLUB_ID, C.CLUB_FEE, AVG(C.CLUB_FEE) AVGINCOME
FROM SUBSCRIPTION S, CLUB C
WHERE S.CLUB_ID = C.CLUB_ID;

3 个答案:

答案 0 :(得分:0)

我建议使用内部联接尝试它当您在查询中包含聚合函数(如avg,sum)时,您必须按所有列分组:

SELECT S.MEMBER_ID, S.CLUB_ID, C.CLUB_FEE, AVG(C.CLUB_FEE) as AVGINCOME
FROM SUBSCRIPTION S INNER JOIN CLUB C
ON S.CLUB_ID = C.CLUB_ID
GROUP BY
S.MEMBER_ID, S.CLUB_ID, C.CLUB_FEE ; 

答案 1 :(得分:0)

学习使用显式JOIN语法。简单规则:从不FROM子句中使用逗号。 始终使用明确的JOIN语法。

在您的情况下,您需要从SELECTGROUP BY中删除列。如果您想要任何会员支付的平均费用,那么您根本不需要GROUP BY

SELECT AVG(C.CLUB_FEE) as AVGINCOME
FROM SUBSCRIPTION S JOIN
     CLUB C
     ON S.CLUB_ID = C.CLUB_ID;

如果您想控制格式,请使用to_char()

SELECT TO_CHAR(AVG(C.CLUB_FEE), '999.99') as AVGINCOME

(查看其他格式的文档)。

或者,投射到小数:

SELECT CAST(AVG(C.CLUB_FEE) AS DECIMAL(10, 2)) as AVGINCOME

答案 2 :(得分:0)

如果您需要显示三列和平均值,而不仅仅是平均值,您可以执行以下操作:

SELECT S.MEMBER_ID, S.CLUB_ID, C.CLUB_FEE, A.AVGINCOME
FROM   SUBSCRIPTION S INNER JOIN CLUB C
                    ON S.CLUB_ID = C.CLUB_ID
                    CROSS JOIN (SELECT AVG(CLUB_FEE) AS AVGINCOME FROM CLUB) A
;

如果您需要将平均四舍五入到小数点后两位,请在子查询中使用ROUND(AVG(CLUB_FEE), 2)

一个更高级的解决方案,它不需要连接(因此它不会扫描CLUB表两次),使用AVG作为分析函数 - 但不进行任何分区。您仍然需要PARTITION BY子句(带有空列列表)来指示它用作分析函数,而不是聚合。

SELECT S.MEMBER_ID, S.CLUB_ID, C.CLUB_FEE,
       ROUND(AVG(C.CLUB_FEE) OVER (PARTITION BY NULL)) AS AVGINCOME
FROM   SUBSCRIPTION S INNER JOIN CLUB C
                      ON S.CLUB_ID = C.CLUB_ID
;

甚至更高级(尽管功能相同) - 需要关键字OVER来表示分析功能,但您也可以将其写为OVER()(甚至不需要提及PARTITION BY NULL)。