Reputation: 5236
In PostgreSQL
database I have table called answers
. This table stores information about how users answered a questions. There are only 4 question in the table. At the same time, the number of users who answered the questions can be dynamic and the user can answer only part of the questions.
Table 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 |
For example, with next code I can find average of the answers for question 1 and 2 of each person who answered for these questions.
select
employee,
avg(
case when question_id in (1, 2) then option_id else null end
) as average_score
from
answers
group by
employee
Result:
| EMPLOYEE | AVERAGE_SCORE |
|----------|---------------|
| Bob | 2 |
| Alex | 2,5 |
| Kate | 3 |
| Oliver | 1 |
Now, I want to know the number of users whose average of the answers for question 1 and 2 is >= than 2. I tried next code but it raise error:
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
ERROR:
SQL Error [42803]: ERROR: aggregate function calls cannot be nested
Upvotes: 0
Views: 3383
Reputation: 384
you have to use having clause.. it can be done simply as
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;
update : It must work now...
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;
Upvotes: 1
Reputation: 1269443
You need to filter after aggregation. That uses a having
clause. In Postgres, you can also use 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;
If you want the count, then use this as a subquery: select count(*) from <the above query>
.
It is strange that you are equating "option_id" with "score", but that is how your question is phrased.
Upvotes: 1