SQL中的(实际值 - 所有行的平均值)的总和

时间:2012-06-14 09:17:03

标签: sql oracle

让我们说我有一张统计学表:

Page | Action | Time
--------------------
Home | Logon  |  12
Home | Logon  |  11
Home | Search |  20
About| Comment|  10

我可以编写一个查询来获取每个页面的平均动作时间:

select Page, avg(Time) from statistics group by Page

但我想要更聪明一点。为了突出显示哪些页面的操作最多,我想得到(所有页面上所有操作的时间平均时间)。我可以在单独的查询中执行此操作:

select avg(Time) from statistics
-> 15
select Page, sum(Time - 15) from statistics group by Page

问题是,有没有办法在单个查询中执行此操作?

显然select Page, sum(Time - avg(Time)) from statistics group by Page不起作用。 Oracle抛出“ORA-00937:不是单组组功能”。

2 个答案:

答案 0 :(得分:6)

您可以使用Window功能:

SELECT  DISTINCT 
        Page, 
        AVG(Time) OVER(PARTITION BY Page) - AVG(Time) OVER() AS Variance
FROM    Statistics

然后稍微扩展,您可以在一个查询中获得许多不同的平均值:

SELECT  Page, 
        Action,
        Time,
        AVG(Time) OVER(PARTITION BY Page, Action) AS AverageActionTime,
        AVG(Time) OVER(PARTITION BY Page) AS AveragePageTime,
        AVG(Time) OVER() AS AverageTime
FROM    Statistics

http://sqlfiddle.com/#!4/42a5f/8

答案 1 :(得分:2)

您可以使用子查询来计算平均时间:

select  stat.Page
,       sum(stat.Time - avg_stat.time) 
from    statistics stat
cross join    
        (
        select  avg(Time) as time
        from    statistics
        ) avg_stat
group by 
        stat.Page