2013-11-27 75 views
2

我想知道是否有可能进行如下的查询。价值和平均值之间的差异(价值)

我有一个表,其中包含idvalue。 Exapmle:

table EXAMPLE 
|id  | value  | 
|  1 |   65| 
|  2 |   13| 
|  3 |   22| 

我想是使查询,返回一组这样的:

|id  | value  | average | difference| 
|  2 |   13|  33.3|  20.3| 
|  3 |   22|  33.3|  11.3| 

是如何处理不同列中的问题?

还有一个问题: 如何在只设置值,是小于或伟大然后均包括

SELECT id, 
     value, 
     (SELECT AVG(value) FROM EXAMPLE) as average 
having 
     value < average. 

我使用having代替where的原因是选择where在执行前因此我不能使用平均值(平均值在查询执行的选择阶段计算)。

我还怀疑我不仅计算一次AVG(值),而且计算表中的每一行。 对吗?如果我是,那很糟糕,它肯定不是我想要的。

请为我介绍一下子查询的MySQL执行顺序或共享此主题的一些链接。 预先感谢您。

+0

我很可怕的遗憾。这是来自问题的第一个版本。编辑。尽管如此,我认为这不是问题中的重要问题。我希望我能够被理解。 – xolodec

回答

5

你必须单独计算的整体平均和强制交叉联接:

SQL Fiddle

select 
    id, 
    value, 
    avgValue, 
    avgValue - value as Diff 
from 
    table1 
    cross join 
    ( 
     select 
      avg(value) as AvgValue 
     from 
      table1 
    ) t2 
where 
    value < avgValue 
+0

非常感谢!我花了数小时寻找如何完成这一点。 – xolodec

0

我想这会做到这一点。你需要分组才能完成聚合功能。

SELECT id, value, (SELECT AVG(value) FROM example GROUP BY id) AS average, 
     average - value AS diff 
FROM example 
GROUP BY id 
HAVING value < average; 
+0

如果按ID分组,则可以得到每个ID的平均值。这不是想要的。此外,你的群组通常是非法的(因为所有非聚合列应该在一个组中)。也就是说,OP还有一个无效查询,甚至缺少基本的'FROM'子句...... – oerkelens

0
select id, value, (select avg(value) from EXAMPLE) as average, 
    (select avg(value) from EXAMPLE) - value as difference 
    from EXAMPLE ; 
0

这也不会把戏

select id, value, 
     (select avg(Value) from table1) as avg, 
     (select avg(Value) from table1) - value as Diff 
from table1 having Diff > 0 
+0

在这种情况下,“avg”只计算一次或每次选择新行时计算? – xolodec

+0

好问题,我认为这取决于优化器。它应该能够识别所有行的平均选择是恒定的,因此计算一次,但我不敢预测对于特定的dbms,这是否为真:) – oerkelens