【问题标题】:Aggregate function calls cannot be nested?聚合函数调用不能嵌套?
【发布时间】:2019-06-20 01:04:15
【问题描述】:

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

【问题讨论】:

    标签: sql postgresql


    【解决方案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”,但这就是您的问题的措辞。

    【讨论】:

    • 感谢您的回答。现在我测试了你的代码,但它引发了错误:column "average_score" does not exist。这也可以在没有计数子查询的情况下完成吗?
    • 我使用完整的表达式 avg(option_id) filter (where question_id in (1, 2)) 而不是 having average_score
    【解决方案2】:

    你必须使用having子句..它可以简单地完成

    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;
    

    【讨论】:

    • 我不确定 [Average Score] 表达式在 PostgreSQL 数据库中的语法是否正确。现在我在[或附近有语法错误。
    • 不知道为什么它在您的上下文中给出错误。不过我用过很多次了,效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    相关资源
    最近更新 更多