当前位置: 首页 > 知识库问答 >
问题:

如何在PostgreSQL窗口分区中执行筛选后的查询?

宋瀚海
2023-03-14

我试图更好地理解PostgreSQL(9.3)窗口函数。假设我有一个简单的表,如下:

SimpleTable
    id int,
    tservice timestamp

并希望:

Select id, tservice , count(*) OVER (PARTITION BY id ....) as counter
from SimpleTable

其中SimpleTable中的记录的tservice时间可以追溯到40年前,但是计数需要限制在每个记录的tservice时间戳之前的三年。

                             3yrs prior   current date
1, 100, '2001-01-01 00:00:00', 0             0
2, 100, '2002-01-01 00:00:00', 1             0
3, 100, '2003-01-01 00:00:00', 2             0 
4, 100, '2004-01-01 00:00:00', 3             0
5, 100, '2005-01-01 00:00:00', 3             0              
6, 100, '2006-01-01 00:00:00', 3             0
7, 100, '2007-01-01 00:00:00', 3             0 
8, 100, '2008-01-01 00:00:00', 3             0
9, 100, '2009-01-01 00:00:00', 3             0
10, 100, '2010-01-01 00:00:00',3             0
11, 100, '2011-01-01 00:00:00',3             0
12, 100, '2012-01-01 00:00:00',3             0
13, 100, '2013-01-01 00:00:00',3             0
14, 100, '2014-01-01 00:00:00',3             1
15, 100, '2015-01-01 00:00:00',3             2
16, 100, '2016-01-01 00:00:00',3             3  (today is 2016-01-06)
     select s1.recid, s1.tservice, s1.client_recid, 
    (select count(*) from simpletable  s2 
        where (s1.tservice - s2.tservice)::INTERVAL <= interval '3 years' and
        s2.tservice < s1.tservice  and
        s2.client_recid = s1.client_recid)
from simpletable s1
order by client_recid, tservice

在几十万张唱片上,这在我的笔记本电脑上需要大约10秒钟。有更快的办法吗?

补充说明:使用Erwin概述的带有游标的函数方法将执行时间减少到146ms。感谢大家提供的优秀教程。

共有1个答案

齐嘉庆
2023-03-14

您所考虑的只是不可能使用窗口函数的框架定义。(你也开始怀疑了。)rangerows子句计算不同的值或行,并且不知道值的含义。

您想要计算在某段时间内下降的所有行,并且需要以不同的方式进行计算。您可以运行相关的子查询或横向的子查询来计算每一行,但这很昂贵。

更聪明的方法是并行运行两个游标并保持运行计数。我为一个非常相似的问题实现了这一点:

    null
 类似资料:
  • 问题内容: PostgreSQL窗口函数的文档似乎暗示您可以在查询的多个位置使用相同的命名窗口。但是,我不知道如何创建命名窗口? 这是一个开玩笑的查询,我试图获取语法,但出现错误: 错误:窗口“ w”不存在 问题答案: 答案实际上在文档中: 条款 可选子句具有一般形式 这是一个例子

  • 我目前有一个大型数据集,但为了简单起见,它看起来如下所示: 我想在此数据集上使用一个窗口函数使其看起来如下所示: 过滤器背后的逻辑应该是,对于每个人,我们按照他们认识的时间长短对他们的朋友进行排序(较高的值位于顶部),然后只保留足够的朋友,以便他们的为100。 例如,Alice只需要Bob,因为她认识他的时间最长,而且他们的超过100。Bob需要Daniel和Alice,因为Bob认识Daniel

  • 我试图使用Django将PostgreSQL表提取到HTML中,当我在PostgreSQL的查询工具中执行空间查询时,我得到了完美的结果,但当我试图从Django执行相同的脚本时,我得到了所有的数据行。谢谢你提前帮忙。 姜戈剧本 HTML

  • 在https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filter-aggregation.html我们了解到: 以上代码显示了我们如何为t恤添加aggs,但我们如何做到: 和

  • 下面是目前为止我所想到的伪代码。任何帮助都将不胜感激!谢谢! 我检查了Table API,但对于流,似乎不支持很多操作,例如OrderBy。

  • 我从geofabrik.de下载了我国家的OSM数据,成功地将其导入到安装在Ubuntu 16.04上的PostgreSQL 9.6中,并使用了几次。我还创建了Web应用程序,它可以正常工作。所以我决定添加另一个功能,从一些点返回最近的特殊点(例如餐馆)。对于一个最近的点,它可以工作,但是当我想要返回它们的数组时,它不工作。于是我分解了自己的问题,发现了奇怪的行为。当我执行以下查询: 它返回: 当