执行聚合函数时如何检索其他列?

How to retrieve other columns when performing an aggregate function?

我一直在尝试从 table 中检索其他列,我在其中执行聚合函数以按日期获取最小数量,这是数据示例:

id   resource   date               quality   ask   ask_volume
1    1          2020-06-08 10:50   0         6.9   5102
2    1          2020-06-08 10:50   1         6.8   2943
3    1          2020-06-08 10:50   2         6.9   25338
4    1          2020-06-08 10:50   3         7.0   69720
5    1          2020-06-08 10:50   4         7.0   9778
6    1          2020-06-08 10:50   5         7.0   297435
7    1          2020-06-08 10:40   0         6.6   611
8    1          2020-06-08 10:40   1         6.6   4331
9    1          2020-06-08 10:40   2         6.7   1000
10   1          2020-06-08 10:40   3         7.0   69720
11   1          2020-06-08 10:40   4         7.0   9778
12   1          2020-06-08 10:40   5         7.0   297435
...

这是我想要得到的结果,所以我可以对其进行加权平均:

date               ask   ask_volume
2020-06-08 10:50   6.8   2943
2020-06-08 10:40   6.6   4331
...

虽然quality0和quality1的ask相同,但是quality1因为ask_volume

我试过经典款:

SELECT date, min(ask) FROM table GROUP BY date;

但是将 ask_volume 添加到列列表将迫使我将其也添加到 GROUP BY,从而弄乱结果。

问题是:

  1. 如何在结果中显示最小ask对应的ask_volume
  2. 并且,如果在同一个 date 上有两条具有相同 ask 值的记录,我怎样才能 ask_volume 显示具有最高值的记录?

我使用 PostgreSQL,但是来自不同数据库的 SQL 也会帮助我理解这个想法。

在标准 SQL 中,您将使用 window 函数:

select *
from (
    select t.*, row_number() over(partition by date order by ask, ask_volume desc) rn
    from mytable 
) t
where rn = 1

在 Postgres 中,这更适合 distinct on:

select distinct on (date) *
from mytable
order by ask, ask_volume desc

你可以用distinct on做你想做的事:

select distinct on (date) t.*
from (select t.*,
order by date, ask, ask_volume desc;

我发现您的 date 专栏令人困惑。它有一个时间部分,所以这个名字具有误导性。

其他答案更简单更好,但这里有一个解决聚合问题的替代方法。在获得每个日期的 min 询问之前,您可以使用子查询仅包含每个询问的每个日期 max ask_volume。

select date, min(ask), max(ask_volume) 
from t
where (date, ask_volume) in (select date, max(ask_volume) 
                             from t
                             group by date, ask)
group by date;

DISTINCT ON 已被建议,但方式不完善。 (目前接受的答案是不正确的。)你就是这样做的:

SELECT DISTINCT ON (date) *
FROM   tbl
ORDER  BY date, ask, ask_volume DESC NULLS LAST;

最重要的是,ORDER BY 中的前导表达式必须在 DISTINCT ON 中的表达式集中。换句话说,对于简单的情况,date 必须是第一个 ORDER BY 表达式。

虽然未排除 null 值(具有 NOT NULL 约束),但您必须按降序首先添加 NULLS LAST 或获取 null 值。

详细解释:

  • Select first row in each GROUP BY group?