如何在 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
字段不是唯一的,这种方法将不起作用!
如果不是,则创建这样的字段。
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 窗口函数的干净方法?