This answer to shows how to produce High/Low/Open/Close values from a ticker:
Retrieve aggregates for arbitrary time intervals

我正在try 基于此实现一个解决方案(第9.2页),但很难获得first_value()的正确值.

到目前为止,我try 了两个问题:

SELECT  
    cstamp,
    price,
    date_trunc('hour',cstamp) AS h,
    floor(EXTRACT(minute FROM cstamp) / 5) AS m5,
    min(price) OVER w,
    max(price) OVER w,
    first_value(price) OVER w,
    last_value(price) OVER w
FROM trades
Where date_trunc('hour',cstamp) = timestamp '2013-03-29 09:00:00'
WINDOW w AS (
    PARTITION BY date_trunc('hour',cstamp), floor(extract(minute FROM cstamp) / 5)
    ORDER BY date_trunc('hour',cstamp) ASC, floor(extract(minute FROM cstamp) / 5) ASC
    )
ORDER BY cstamp;

下面是一个结果:

        cstamp         price      h                 m5  min      max      first    last
"2013-03-29 09:19:14";77.00000;"2013-03-29 09:00:00";3;77.00000;77.00000;77.00000;77.00000

"2013-03-29 09:26:18";77.00000;"2013-03-29 09:00:00";5;77.00000;77.80000;77.80000;77.00000
"2013-03-29 09:29:41";77.80000;"2013-03-29 09:00:00";5;77.00000;77.80000;77.80000;77.00000
"2013-03-29 09:29:51";77.00000;"2013-03-29 09:00:00";5;77.00000;77.80000;77.80000;77.00000

"2013-03-29 09:30:04";77.00000;"2013-03-29 09:00:00";6;73.99004;77.80000;73.99004;73.99004

正如你所看到的,77.8是not,我认为这是first_value()的正确值,应该是77.0.

我想这可能是因为WINDOW中不明确的ORDER BY,所以我把它改为

ORDER BY cstamp ASC 

但这似乎也打乱了PARTITION人:

        cstamp         price      h                 m5  min      max      first    last
"2013-03-29 09:19:14";77.00000;"2013-03-29 09:00:00";3;77.00000;77.00000;77.00000;77.00000

"2013-03-29 09:26:18";77.00000;"2013-03-29 09:00:00";5;77.00000;77.00000;77.00000;77.00000
"2013-03-29 09:29:41";77.80000;"2013-03-29 09:00:00";5;77.00000;77.80000;77.00000;77.80000
"2013-03-29 09:29:51";77.00000;"2013-03-29 09:00:00";5;77.00000;77.80000;77.00000;77.00000

"2013-03-29 09:30:04";77.00000;"2013-03-29 09:00:00";6;77.00000;77.00000;77.00000;77.00000

因为max和last的值现在是vary within the partition.

我做错了什么?有人能帮我更好地理解WINDOWPARTITIONORDER之间的关系吗?


虽然我有一个答案,但这里有一个精简的pg_转储,允许任何人重新创建表格.唯一不同的是表名.

CREATE TABLE wtest (
    cstamp timestamp without time zone,
    price numeric(10,5)
);

COPY wtest (cstamp, price) FROM stdin;
2013-03-29 09:04:54 77.80000
2013-03-29 09:04:50 76.98000
2013-03-29 09:29:51 77.00000
2013-03-29 09:29:41 77.80000
2013-03-29 09:26:18 77.00000
2013-03-29 09:19:14 77.00000
2013-03-29 09:19:10 77.00000
2013-03-29 09:33:50 76.00000
2013-03-29 09:33:46 76.10000
2013-03-29 09:33:15 77.79000
2013-03-29 09:30:08 77.80000
2013-03-29 09:30:04 77.00000
\.

推荐答案

SQL Fiddle

您使用的所有函数都作用于窗口框架,而不是分区.如果省略,则帧结束为当前行.要使窗口框架成为整个分区,请在frame子句(range...)中声明它:

SELECT  
    cstamp,
    price,
    date_trunc('hour',cstamp) AS h,
    floor(EXTRACT(minute FROM cstamp) / 5) AS m5,
    min(price) OVER w,
    max(price) OVER w,
    first_value(price) OVER w,
    last_value(price) OVER w
FROM trades
Where date_trunc('hour',cstamp) = timestamp '2013-03-29 09:00:00'
WINDOW w AS (
    PARTITION BY date_trunc('hour',cstamp) , floor(extract(minute FROM cstamp) / 5)
    ORDER BY cstamp
    range between unbounded preceding and unbounded following
    )
ORDER BY cstamp;

Postgresql相关问答推荐

使用PGx在围棋中执行多条SQL语句

sqlalchemy在Flask 下运行时出现无法解释的错误

错误:用户需要系统密码:postgres

Ubuntu 上的 PostgreSQL 安装:找不到initdb命令

无法使用golang在postgresql中使用自定义类型插入/更新数据

如何在postgresql中按时间查询

Postgres内部如何计算月份间隔

PostgreSQL - 继承表的常见自动增量

postgresql 更新错误ERROR: invalid input syntax for type boolean:

安装 pg gem 失败,mkmf.rb 找不到 ruby​​ 的头文件(Mac OSX 10.6.5)

将 SELECT 结果作为参数传递给 postgreSQL 函数

在 PL/pgSQL 中声明行类型变量

Postgres 删除表语法错误

使用 current_setting() 判断值

与 Oracle 的 CONNECT BY ... START WITH 等效的 PostgreSQL 语法是什么?

在 MAC OS X 10.6 for PostgreSQL 上设置 SHMMAX 等值

使用 RPostgreSQL 写入特定模式

python postgres 我可以 fetchall() 100 万行吗?

使用python将数据从csv复制到postgresql

PostgreSQL - GROUP BY 子句或用于聚合函数