如何在PostgreSQL 8.3中执行窗口函数

时间:2012-05-16 17:21:34

标签: postgresql window-functions

我已经编写了一个要部署到heroku的Web应用程序。我用PostgreSQL 9.1.2编写了它。但似乎heroku上的免费共享数据库只有postgres 8.3。他们正在升级到9.很快就会有一些东西,但在那之前,我的一个SQL查询无法正常工作。它是:

SELECT id, route_id, location_id, order_id, blogtext,
  lead(id) over (PARTITION BY route_id ORDER BY order_id ASC) AS next_id,
  lead(location_id) over (PARTITION BY route_id ORDER BY order_id ASC) AS next_location_id,
  lag(id) over (PARTITION BY route_id ORDER BY order_id ASC) as previous_id,
  lag(location_id) over (PARTITION BY route_id ORDER BY order_id ASC) AS previous_location_id,
  row_number() over (PARTITION BY route_id ORDER BY order_id ASC) AS indx

是否可以重写这个以在PostgreSQL 8.3上工作?

1 个答案:

答案 0 :(得分:2)

请注意,PostgreSQL Window functions doesn't exists中的before 8.4


<强> EDIT2:

你让我非常好奇,而且我已经玩弄了这些问题。

首先要注意的一些事项:

  1. 为了达到理想的效果,您必须多次与自己联系。鉴于PostgreSQL 8.3不支持CTE,我创建了一个视图。幸运的是,在您的情况下,只需要一个视图,因为您对所有窗口函数使用相同的OVER ()条件;

  2. row_number应该用于操作数据子集,因此我已将此字段添加到视图中;

  3. 要形成PARTITION,您应该在=子句中的所有字段的联接表上使用PARTITION运算符;

  4. row_number使用子查询(无连接)形成,并计算与分区匹配的所有行,并使ORDER BY个字段小于或等于当前的字段。 请注意,如果ORDER BY字段不唯一,则此方法无效! 如果不是这样,那么创建这样的字段。

  5. 要模拟非ORDER BY个函数的row_number子句,请加入row_number个字段,使其成为+1-1,{{加入方的1}}或min(),分别匹配max()lead()lag()first_value()函数。

  6. 请考虑点 4 以上!

    您的查询可以通过以下方式更改(在使用前比较输出):

    last_value()

    我已使用Window functions and more "local" aggregation中的修改后的示例数据并创建了一个沙箱,以显示它在SQL Fiddle上的工作原理。

    尽管如此,鉴于所有开发工作都是在9.1.2完成的,我会在这样做之前再三考虑。