【问题标题】:PostgreSQL LIMIT over WINDOWPostgreSQL 限制超过窗口
【发布时间】:2012-03-20 20:08:28
【问题描述】:

我想知道是否有一种简单的方法可以将查询限制在前 n 个窗口中。

即说我有类似的东西

SELECT field1
      ,field2
      ,field3
      ,sum(field2) over (partition by field1) sum2
      ,sum(field3) over (partition by field1) sum3
FROM table1
GROUP BY field1, field2, field3
ORDER BY sum2 DESC LIMIT 100

上面的查询返回前 100 个记录,而不是前 100 个窗口(这是有道理的)

我想要的是前 100 个 sum2 窗口,即使该窗口内可能有多行。所以我可能会得到 400 条记录,但只有前 100 个窗口。

希望这是有道理的。

【问题讨论】:

  • 为什么不按列分组?
  • 我需要保留每条记录中的详细信息。我正在尝试在同一结果集中获取详细信息和聚合。实际查询要大得多。这只是问题的一个示例。
  • 仍然没有得到..但是您必须先按列分组...

标签: postgresql limit result-partitioning


【解决方案1】:

在评论和思考之后,我认为以下查询可以满足您的需求。

我选择查询产生的前 100 个“窗口”并返回所有落入这些窗口的行。由于窗口由field1 划分,这实际上是field1 的100 个不同值,其中sum2 最大。对于sum2 上的关系,我的查询中较大的field1 获胜(您没有指定)。

WITH x AS (
    SELECT field1
          ,field2
          ,field3
          ,sum(field2) over w sum2
          ,sum(field3) over w sum3
    FROM   table1
    GROUP  BY field1, field2, field3
    WINDOW w AS (PARTITION BY field1) 
    )
    , y AS (
    SELECT field1
    FROM   x
    GROUP  BY sum2, field1
    ORDER  BY sum2 DESC, field1 DESC
    LIMIT  100
    )
SELECT x.*
FROM   y
JOIN   x USING (field1)
ORDER  BY sum2 DESC, field1 DESC, field2 DESC, field3 DESC;

关键是在一个 CTE 中生成聚合值,从另一个 CTE 中的那些中挑选出 100 个获胜窗口(也可以用 DISTINCT 完成,我选择了 GROUP BY / ORDER BY),然后加入结果返回到第一个 CTE 以获取这些窗口的所有行。

总而言之,这是一个相当复杂的查询。

【讨论】:

  • 感谢您的快速回复。无论如何,我似乎得到了 100 行。我不认为我清楚地解释了我所追求的。我正在寻找的是组内的每条记录。所以我会得到前 100 个窗口,每个记录也在那个窗口中。因此,如果每个窗口中有 5 条记录,并且我想要前 100 个窗口,那么我最终会得到 500 条记录。
  • @PhilFreeman:实际上,您希望field1 有 100 个不同的值,并且 (field2, field3) 的每个组合都有一行?您确定要GROUP BY field1, field2, field3 并在此之前消除重复项 - 所以重复项不会添加到总和中吗?对于像您这样的复杂案例,使用一些样本值和预期的样本输出会更容易 - 在您的问题中,not in cmets.
  • 是的。非常感谢。
猜你喜欢
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 1970-01-01
  • 2018-02-01
  • 1970-01-01
  • 2011-09-20
  • 2018-12-15
相关资源
最近更新 更多