Postgres中的时间序列查询

bpaul

这是@Erwin对Postgres中的有效时间序列查询的回答中的一个问题

为了使事情简单,我将使用与该问题相同的表结构

id | widget_id | for_date | score |

最初的问题是要获取范围内每个日期的每个小部件的分数。如果日期没有小部件的条目,则显示该小部件上一个条目的得分。如果所有数据都包含在您要查询的范围内,则使用交叉联接和窗口函数的解决方案效果很好。我的问题是,即使以前的分数超出了我们正在查看的日期范围,我也想要它。

示例数据:

INSERT INTO score (id, widget_id, for_date, score) values
(1, 1337, '2012-04-07', 52),
(2, 2222, '2012-05-05', 99),
(3, 1337, '2012-05-07', 112),
(4, 2222, '2012-05-07', 101);

当我查询2012年5月5日至5月10日的范围(即generate_series('2012-05-05'::date, '2012-05-10'::date, '1d'))时,我希望获得以下信息:

DAY          WIDGET_ID  SCORE
May, 05 2012    1337    52
May, 05 2012    2222    99
May, 06 2012    1337    52
May, 06 2012    2222    99
May, 07 2012    1337    112
May, 07 2012    2222    101
May, 08 2012    1337    112
May, 08 2012    2222    101
May, 09 2012    1337    112
May, 09 2012    2222    101
May, 10 2012    1337    112
May, 10 2012    2222    101

迄今为止最好的解决方案(也是@Erwin的解决方案)是:

SELECT a.day, a.widget_id, s.score
FROM  (
   SELECT d.day, w.widget_id
         ,max(s.for_date) OVER (PARTITION BY w.widget_id ORDER BY d.day) AS effective_date
   FROM  (SELECT generate_series('2012-05-05'::date, '2012-05-10'::date, '1d')::date AS day) d
   CROSS  JOIN (SELECT DISTINCT widget_id FROM score) AS w
   LEFT   JOIN score s ON s.for_date = d.day AND s.widget_id = w.widget_id
   ) a
LEFT JOIN  score s ON s.for_date = a.effective_date AND s.widget_id = a.widget_id
ORDER BY a.day, a.widget_id;

但是,正如您在此SQL Fiddle中所看到的那样,它在前两天为小部件1337生成了空分数。我希望看到第1行的得分为52。

有可能以一种有效的方式做到这一点吗?

欧文·布兰德斯特

@Roman所述DISTINCT ON可以解决此问题。相关答案的详细信息:

子查询通常比CTE快一点:

SELECT DISTINCT ON (d.day, w.widget_id)
       d.day, w.widget_id, s.score
FROM   generate_series('2012-05-05'::date, '2012-05-10'::date, '1d') d(day)
CROSS  JOIN (SELECT DISTINCT widget_id FROM score) AS w
LEFT   JOIN score s ON s.widget_id = w.widget_id AND s.for_date <= d.day
ORDER  BY d.day, w.widget_id, s.for_date DESC;

您可以使用集合返回函数,例如列表中的FROM表格。

SQL小提琴

一个多列索引应该是性能的关键:

CREATE INDEX score_multi_idx ON score (widget_id, for_date, score)

score仅包括第三列,以使其成为Postgres 9.2或更高版本中覆盖索引您不会在早期版本中包括它。

当然,如果您有许多小部件且工作日很长,则会CROSS JOIN产生很多行,并带有价格标签。仅选择您实际需要的小部件和日期。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Postgres - 查询时间序列模式

来自分类Dev

在Postgress中查询时间序列

来自分类Dev

在Postgres中识别重复的时间序列

来自分类Dev

在 Postgres 中查询空的时间范围

来自分类Dev

从Postgres DB对dplyr中的时间序列数据进行下采样

来自分类Dev

范围查询-CQL Cassandra中时间序列的数据建模

来自分类Dev

Postgres查询-24小时时间序列按特定列过滤,但每小时仍返回行

来自分类Dev

如何在RDS Postgres中设置查询超时时间

来自分类Dev

时间相关的postgres查询速度

来自分类Dev

在范围查询中查询活动和过时的Prometheus时间序列的最新值

来自分类Dev

频谱中的时间序列

来自分类Dev

默认时区不适用于postgres中的序列化查询

来自分类Dev

SQL查询按时间序列分组

来自分类Dev

使用Hive查询分析时间序列数据

来自分类Dev

在postgres中查询json

来自分类Dev

Postgres中的格式查询

来自分类Dev

mongodb中的时间序列数据-如何查询嵌入式文档

来自分类Dev

使用向量作为输入来查询R中不同时间序列的函数

来自分类Dev

如何在Access中创建时间序列并可以在查询中使用它

来自分类Dev

始终在Thunderbird 68中以时间排序列表的形式打开搜索查询吗?

来自分类Dev

R中的时间序列-重塑?

来自分类Dev

在R中绘制时间序列

来自分类Dev

时间序列数据中的ValueError

来自分类Dev

从时间序列中删除小时

来自分类Dev

重塑R中的时间序列

来自分类Dev

R中的时间序列数据

来自分类Dev

R中的时间序列-重塑?

来自分类Dev

R中的时间序列模拟

来自分类Dev

PostgreSQL 中的时间序列预测