带有 LIMIT 的 PostgreSQL 窗口函数

Posted

技术标签:

【中文标题】带有 LIMIT 的 PostgreSQL 窗口函数【英文标题】:PostgreSQL window function with LIMIT 【发布时间】:2014-07-31 13:52:03 【问题描述】:

下面的查询将来自first 的结果分组到4 个等距的日期箱中,并在每个箱中聚合the_value 的平均值。

WITH first as(
SELECT
    extract(EPOCH FROM foo.t_date) as the_date,
    foo_val as the_value
FROM bar
INNER JOIN foo
ON
    foo.user_id = bar.x_id
    and
    foo.user_name = 'xxxx'
)
SELECT bin, round(sum(bin_sum) OVER w /sum(bin_ct) OVER w, 2) AS running_avg
FROM  (
   SELECT width_bucket(first.the_date
                     , x.min_epoch, x.max_epoch, x.bins) AS bin
        , sum(first.the_value) AS bin_sum
        , count(*)   AS bin_ct
   FROM   first
       , (SELECT MIN(first.the_date) AS min_epoch
               , MAX(first.the_date) AS max_epoch
               , 4 AS bins
          FROM  first
         ) x
   GROUP  BY 1
   ) sub
WINDOW w AS (ORDER BY bin)
ORDER  BY 1;

我希望能够只计算每个 bin 中最低的 20 个 the_value 的平均值。从 *** 上的其他帖子中,我看到这是可能的,也许 ORDER BY the_valuerank() 是最好的方法。但我的困难是我不确定我当前的查询应该在哪里修改以实现这一点。

任何见解都将不胜感激。

Postgres 9.3 版

【问题讨论】:

任何见解将不胜感激可用数据将不胜感激。 以及您的 Postgres 版本 (always)。 @ErwinBrandstetter - 以上查询中作用于first 的部分取自您提交给link 的答案。 @user3204587:我觉得它看起来很眼熟。 ;) 【参考方案1】:

在每个 bin 上使用 row_number()。 先计算行号rn,然后在下一步应用WHERE rn < 21

WITH first AS (
   SELECT extract(EPOCH FROM foo.t_date) AS the_date
        , foo_val AS the_value
   FROM bar
   JOIN foo ON foo.user_id = bar.x_id
           AND foo.user_name = 'xxxx'
   )
, x AS (
   SELECT MIN(the_date) AS min_epoch
        , MAX(the_date) AS max_epoch
   FROM  first
   )
, y AS (
   SELECT width_bucket(f.the_date, x.min_epoch, x.max_epoch, 4) AS bin, *
   FROM   first f, x
   )
, z AS (
   SELECT row_number() OVER (PARTITION BY bin ORDER BY the_value) AS rn, *
   FROM   y
   )
SELECT bin, round(sum(bin_sum) OVER w / sum(bin_ct) OVER w, 2) AS running_avg
FROM  (
   SELECT bin
        , sum(the_value) AS bin_sum
        , count(*)       AS bin_ct
   FROM   z
   WHERE  rn < 21   -- max 20 lowest values
   GROUP  BY 1
   ) sub
WINDOW w AS (ORDER BY bin)
ORDER  BY 1;

CTE yz 可以混为一谈。同样,firstx 可以混为一谈。 但这样更清楚。

未经测试,因为我们没有测试数据。

【讨论】:

y AS部分你写FROM first f, x和width_bucket中的字段前面是f.。是first f == first as f @user3204587: Yes.

以上是关于带有 LIMIT 的 PostgreSQL 窗口函数的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL LIMIT 子句

带有“lag()”窗口函数的 PostgreSQL 更新查询

SQL 窗口函数 - SELECT DISTINCT ORDER BY LIMIT

postgresql,奇怪的 OFFSET/LIMIT 行为(记录顺序)

PostgreSql 分页limit

连续 ID 块上的 PostgresQL 窗口函数