在AVG函数中使用SELECT子句

时间:2014-12-18 21:46:06

标签: mysql

我有下表:

table: people
id  |   name    |   income
==========================
1    Bob         10
2    John        5
3    Amy         15
4    Alyson      5
5    Henry       20

我想取一些选定行数的平均值,如下所示:

SELECT
    id,
    name,
    (AVG(
        SELECT income FROM people WHERE FIND_IN_SET(id, '1,2,3')
    ) - income) AS averageDiff
FROM people;

我希望得到这样的结果:

id  |   name    |   averageDiff
==========================
1    Bob         0
2    John        5
3    Amy         -5
4    Alyson      -5
5    Henry       10

但是,当我尝试在AVG函数中使用SELECT子句时,我收到错误(#1064)。我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

使用以下语法:

SELECT avg(income) FROM people WHERE FIND_IN_SET(id, '1,2,3')

您需要以这种方式将上述查询括在括号中:

SELECT
......
    (ABS(IFNULL(`age`, 0)  
      - IFNULL((SELECT AVG(age) FROM people WHERE FIND_IN_SET(id, '1,2,3')), 0)))
    + (ABS(IFNULL(`income`, 0) 
       - IFNULL((SELECT AVG(income) FROM people WHERE FIND_IN_SET(id, '1,2,3')), 0))) AS sumAvg
FROM `people`
....

答案 1 :(得分:0)

如果您希望每个人的平均值作为起点,请使用查询计算并将其与您想要包含的人交叉加入:

SELECT
  people.id,
  people.name,
  people.income - av.avgincome AS averageDiff
FROM people
CROSS JOIN (SELECT AVG(income) AS avgincome FROM people) av
WHERE people.ID IN (1, 2, 3)

如果您想要ID为1,2或3的人的子集的平均值作为起点,您可以这样做:

SELECT
  people.id,
  people.name,
  people.income - av.avgincome AS averageDiff
FROM people
CROSS JOIN (
  SELECT AVG(income) AS avgincome
  FROM people
  WHERE ID IN (1, 2, 3)) av
WHERE people.ID IN (1, 2, 3)

这两种方法都避免了相关子查询(意味着基于顶级表的列名称为SELECT),这对于大型记录集来说很慢。

FIND_IN_SET(people.id, '1,2,3') will work, but if you have an index on table.id the IN(1,2,3)`会快得多。即使你没有索引,它也可能会更快。