聚合函数调用不能嵌套吗?

时间:2019-06-18 16:27:06

标签: sql postgresql

PostgreSQL数据库中,我有一个名为answers的表。该表存储有关用户如何回答问题的信息。表中只有4个问题。同时,回答问题的用户数量可以动态变化,并且用户只能回答部分问题。

answers

| EMPLOYEE | QUESTION_ID | QUESTION_TEXT          | OPTION_ID | OPTION_TEXT  |
|----------|-------------|------------------------|-----------|--------------|
| Bob      | 1           | Do you like soup?      | 1         | Yes          |
| Alex     | 1           | Do you like soup?      | 2         | No           |
| Kate     | 1           | Do you like soup?      | 3         | I don't know |
| Bob      | 2           | Do you like ice cream? | 1         | Yes          |
| Alex     | 2           | Do you like ice cream? | 3         | I don't know |
| Oliver   | 2           | Do you like ice cream? | 1         | Yes          |
| Bob      | 3           | Do you like summer?    | 2         | No           |
| Alex     | 3           | Do you like summer?    | 1         | Yes          | 
| Jack     | 3           | Do you like summer?    | 2         | No           |
| Bob      | 4           | Do you like winter?    | 3         | I don't know |
| Alex     | 4           | Do you like winter?    | 1         | Yes          |
| Oliver   | 4           | Do you like winter?    | 3         | I don't know |

例如,使用下一个代码,我可以找到每个回答这些问题的人对问题1和2的平均回答。

select
    employee,
    avg(
        case when question_id in (1, 2) then option_id else null end
    ) as average_score
from
    answers
group by
    employee

结果:

| EMPLOYEE | AVERAGE_SCORE |
|----------|---------------|
| Bob      | 2             |
| Alex     | 2,5           |
| Kate     | 3             |
| Oliver   | 1             |

现在,我想知道问题1和2的平均答案> =大于2的用户数量。我尝试了下一个代码,但它会引发错误:

select
    count(
        avg(
            case when question_id in (1, 2) then option_id else null end
        )
    ) as average_score
from
    answers
where
    average_score >= 2
group by
    answers.employee

错误:

SQL Error [42803]: ERROR: aggregate function calls cannot be nested

2 个答案:

答案 0 :(得分:1)

您需要在汇总后过滤 。该语句使用having子句。在Postgres中,您也可以使用filter

select employee,
       avg(option_id) filter (where question_id in (1, 2)) as average_score
from answers
group by employee
having avg(option_id) filter (where question_id in (1, 2)) > 2;

如果要计数,则将其用作子查询:select count(*) from <the above query>

奇怪的是,您将“ option_id”与“ score”等同,但这就是您的问题的表达方式。

答案 1 :(得分:0)

您必须使用hading子句..只需完成

select employee, [Average Score] = avg(case when question_id in (1, 2) 
                                            then option_id else null 
                                            end
                                       ) 
from answers group by employee having average_score > 2;

更新: 它必须现在可以工作...

select employee, average_score = avg(case when question_id in (1, 2) 
                                            then option_id else null 
                                            end
                                       ) 
from answers group by employee having average_score > 2;