PostgreSQL - 条件聚合 - Select语句中的Avg()

时间:2013-06-20 12:48:57

标签: postgresql select aggregate-functions

我有这张桌子

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

我想用一个select语句构建一个查询,该语句返回下面显示的行。 平均值(标记) - 仅当Mark> 0时才应该是平均值 Sum(Points) - 应该是所有记录的总和。

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

任何人都可以指出正确的语法吗?

我相信它应该:

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

3 个答案:

答案 0 :(得分:9)

怎么样:

select user,
       avg(case when mark > 0 then mark end),
       sum(mark)
from   ...

答案 1 :(得分:8)

从版本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"

答案 2 :(得分: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

应该如此诀窍。