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

Posted

技术标签:

【中文标题】如何在 PostgreSQL 8.3 中执行窗口函数【英文标题】:How can you do window functions in PostgreSQL 8.3 【发布时间】:2012-05-16 17:21:33 【问题描述】:

我编写了一个要部署到 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 上工作?

【问题讨论】:

您需要等待 9.x 升级 【参考方案1】:

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


EDIT2:

你让我非常好奇,我已经玩弄了这些查询。

首先要注意的几点:

    为了达到预期的效果,您必须多次将表与自身连接。鉴于 PostgreSQL 8.3 不支持 CTE,我创建了一个视图。幸运的是,您的情况只需要一个视图,因为您对所有窗口函数使用相同的 OVER () 条件;

    row_number应该用于对数据子集进行操作,所以我在视图中添加了这个字段;

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

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

    1234563分别匹配lead()lag()first_value()last_value()函数。

请考虑上面的第 4 点!

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

-- First, create a support view
CREATE VIEW table_v AS
SELECT id, route_id, location_id, order_id, blogtext,
       (SELECT count(*) FROM table
         WHERE route_id = t.route_id AND order_id <= t.order_id) AS row_number
  FROM table t;

-- Now, the query
SELECT t.id, t.route_id, t.location_id, t.order_id, t.blogtext,
       tlead.id AS next_id, tlead.location_id AS next_location_id,
       tlag.id AS previous_id, tlag.location_id AS previous_location_id,
       t.row_number AS indx
  FROM table_v t
  LEFT JOIN table_v tlead
    ON tlead.route_id = t.route_id AND tlead.row_number = t.row_number + 1
  LEFT JOIN table_v tlag
    ON tlag.route_id = t.route_id AND tlag.row_number = t.row_number - 1
  -- 
  -- proceed with the query here
  -- ...

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

尽管如此,鉴于所有开发都是在 9.1.2 上完成的,我还是会三思而后行。

【讨论】:

不能用joins来做吗? @dan,我提供了一个基于联接的解决方案,希望它适合你。

以上是关于如何在 PostgreSQL 8.3 中执行窗口函数的主要内容,如果未能解决你的问题,请参考以下文章

phpadmin4 支持 postgresql 8.3 吗?

在 django ORM 中使用 postgresql 窗口函数的干净方法?

PostgreSQL 8.3 权限未更新 - 使用错误?

Postgresql 8.3,不使用索引的简单查询

如何在 Postgresql 窗口函数的 PARTITION BY 中包含当前行

如何在 PostgreSQL 中导出数据库的模式?