Return 行是 Postgresql 中一列的最大值
Return rows that are max of one column in Postgresql
来自我的示例数据 table test_table
:
date symbol value created_time
2010-01-09 symbol1 101 3847474847
2010-01-10 symbol1 102 3847474847
2010-01-10 symbol1 102.5 3847475500
2010-01-10 symbol2 204 3847474847
2010-01-11 symbol1 109 3847474847
2010-01-12 symbol1 105 3847474847
2010-01-12 symbol2 206 3847474847
鉴于上面的 table,我试图找到放在 table 上的最佳索引(日期、符号、值和 created_time 组合起来应该是唯一的)和与它一起查询 return 以下内容:
date symbol value created_time
2010-01-09 symbol1 101 3847474847
2010-01-10 symbol1 102.5 3847475500
2010-01-10 symbol2 204 3847474847
2010-01-11 symbol1 109 3847474847
2010-01-12 symbol1 105 3847474847
2010-01-12 symbol2 206 3847474847
我正在为这三个具有最大 created_time 列的每组寻找数据的日期、符号、值列(基本上是上例中的第 1、3、4、5、6、7 行returned).
目前我已经尝试过这个索引...
CREATE UNIQUE INDEX "test_table_date_symbol_value_created_time"
ON "test_table" USING btree (date, symbol, value, created_time)
我正在使用这个查询。不知道是不是最有效的方法,还是比较慢。
select *
from(
select date,
symbol,
value,
created_time,
max(created_time) over (partition by date, symbol) as max_created_time
from "test_table"
) t
where symbol in ('symbol1', 'symbol2') and created_time = max_created_time
Postgres 支持 window functions 适合这种情况:
select date, symbol, value, created_time
from (select *,
rank() over (partition by date, symbol order by created_time desc) as rownum
from test_table) x
where rownum = 1
对于 date
、symbol
的每个组合,此查询 returns 来自具有最高(即 last) created_time
其中 date
和 symbol
.
我建议这个索引:
CREATE UNIQUE INDEX test_table_idx
ON test_table (date, symbol, created_time, value)
它是一个 覆盖 索引(具有您查询所需的所有值,无需访问实际的 table,而您已经拥有),但是请注意 created_time
出现在 之前 value
,因此数据已经在其分区顺序中,并且 value
是最不重要的属性,因为它不t 参与任何决定 return.
的行
选择:
SELECT * FROM test_table tt
WHERE NOT EXISTS (
SELECT * FROM test_table nx
WHERE nx."date" = tt."date"
AND nx.symbol = tt.symbol
AND nx.created_time > tt.created_time
);
Postgresql 有非常方便的 distinct on
select distinct on (symbol, date) *
from t
order by symbol, date, created_time desc
https://www.postgresql.org/docs/current/static/sql-select.html#SQL-DISTINCT
来自我的示例数据 table test_table
:
date symbol value created_time
2010-01-09 symbol1 101 3847474847
2010-01-10 symbol1 102 3847474847
2010-01-10 symbol1 102.5 3847475500
2010-01-10 symbol2 204 3847474847
2010-01-11 symbol1 109 3847474847
2010-01-12 symbol1 105 3847474847
2010-01-12 symbol2 206 3847474847
鉴于上面的 table,我试图找到放在 table 上的最佳索引(日期、符号、值和 created_time 组合起来应该是唯一的)和与它一起查询 return 以下内容:
date symbol value created_time
2010-01-09 symbol1 101 3847474847
2010-01-10 symbol1 102.5 3847475500
2010-01-10 symbol2 204 3847474847
2010-01-11 symbol1 109 3847474847
2010-01-12 symbol1 105 3847474847
2010-01-12 symbol2 206 3847474847
我正在为这三个具有最大 created_time 列的每组寻找数据的日期、符号、值列(基本上是上例中的第 1、3、4、5、6、7 行returned).
目前我已经尝试过这个索引...
CREATE UNIQUE INDEX "test_table_date_symbol_value_created_time"
ON "test_table" USING btree (date, symbol, value, created_time)
我正在使用这个查询。不知道是不是最有效的方法,还是比较慢。
select *
from(
select date,
symbol,
value,
created_time,
max(created_time) over (partition by date, symbol) as max_created_time
from "test_table"
) t
where symbol in ('symbol1', 'symbol2') and created_time = max_created_time
Postgres 支持 window functions 适合这种情况:
select date, symbol, value, created_time
from (select *,
rank() over (partition by date, symbol order by created_time desc) as rownum
from test_table) x
where rownum = 1
对于 date
、symbol
的每个组合,此查询 returns 来自具有最高(即 last) created_time
其中 date
和 symbol
.
我建议这个索引:
CREATE UNIQUE INDEX test_table_idx
ON test_table (date, symbol, created_time, value)
它是一个 覆盖 索引(具有您查询所需的所有值,无需访问实际的 table,而您已经拥有),但是请注意 created_time
出现在 之前 value
,因此数据已经在其分区顺序中,并且 value
是最不重要的属性,因为它不t 参与任何决定 return.
选择:
SELECT * FROM test_table tt
WHERE NOT EXISTS (
SELECT * FROM test_table nx
WHERE nx."date" = tt."date"
AND nx.symbol = tt.symbol
AND nx.created_time > tt.created_time
);
Postgresql 有非常方便的 distinct on
select distinct on (symbol, date) *
from t
order by symbol, date, created_time desc
https://www.postgresql.org/docs/current/static/sql-select.html#SQL-DISTINCT