执行聚合函数时如何检索其他列?
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
...
虽然quality
0和quality
1的ask
相同,但是quality
1因为ask_volume
高
我试过经典款:
SELECT date, min(ask) FROM table GROUP BY date;
但是将 ask_volume
添加到列列表将迫使我将其也添加到 GROUP BY
,从而弄乱结果。
问题是:
- 如何在结果中显示最小
ask
对应的ask_volume
?
- 并且,如果在同一个
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?
我一直在尝试从 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
...
虽然quality
0和quality
1的ask
相同,但是quality
1因为ask_volume
高
我试过经典款:
SELECT date, min(ask) FROM table GROUP BY date;
但是将 ask_volume
添加到列列表将迫使我将其也添加到 GROUP BY
,从而弄乱结果。
问题是:
- 如何在结果中显示最小
ask
对应的ask_volume
? - 并且,如果在同一个
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?