返回Postgresql中最多一列的行

时间:2017-01-25 18:11:06

标签: sql postgresql greatest-n-per-group

我的表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

根据上面的表格,我试图找到放在表格上的最佳索引(日期,符号,值和created_time应该是唯一的),并且查询与它一起返回以下内容:

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行)。

目前我已尝试过这个索引...

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

3 个答案:

答案 0 :(得分:1)

Postgres支持适合这种情况的window functions

//onload event-- to set the values
$scope.$on('$stateChangeSuccess', function () {

    $scope.cart=sharedCartService.cart;
    $scope.total_qty=sharedCartService.total_qty;
    $scope.total_amount=sharedCartService.total_amount;     
});    

对于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的每个组合,此查询会返回最高行的symbolvalue(即 last created_timecreated_time的{​​{1}}。

我会建议这个索引:

date

这是一个覆盖索引(包含查询所需的所有值,无需访问实际的表,以及您已经拥有的那些),但请注意symbol来< em>在 CREATE UNIQUE INDEX test_table_idx ON test_table (date, symbol, created_time, value) 之前,因此数据已经在其分区顺序中,created_time是最不重要的属性,因为它不参与确定要返回的行。< / p>

答案 1 :(得分:1)

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

答案 2 :(得分:0)

替代:

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
    );