9

I have this table

| user         | Mark       | Points   |
|--------------|------------|----------|
| John         |    0       |    2     |
| Paul         |    5       |    3     |
| John         |    4       |    4     |
| Paul         |    7       |    5     |

I would like to build a query with one select statement that returns the rows shown below. Avg(Mark) - should be average only if Mark>0 Sum(Points) - should be sum of all records.

| user         | Avg(Mark)  | Sum(Points) |
|--------------|------------|-------------|
| John         |    4       |    6        |
| Paul         |    6       |    8        |

Can anyone point to a proper syntax?

I believe it should like :

select user, avg(Mark>0), sum(Points) from Table group by user;
4

3 回答 3

23

从 9.4 版开始,PostgreSQL 直接支持过滤聚合。

https://www.postgresql.org/docs/9.4/static/sql-expressions.html

如果指定了 FILTER,则只有 filter_clause 计算结果为 true 的输入行被馈送到聚合函数;其他行被丢弃。

通过使用它,您的示例可以重写为:

SELECT
    "user",
    AVG(mark) FILTER (WHERE mark > 0),
    SUM(points)
FROM
    "table"
GROUP BY
    "user"
于 2018-02-20T07:18:37.343 回答
13

怎么样:

select user,
       avg(case when mark > 0 then mark end),
       sum(mark)
from   ...
于 2013-06-20T13:26:11.410 回答
1
select
    user, -- very bad choice for column name, but i assume it's just SO example, not real column
    sum( mark ) / count (nullif(mark, 0))
from
    table
group by
    user

应该是这样的伎俩。

于 2013-06-20T12:55:52.680 回答