为选择中的每一行调用一个函数 - Postgres

Posted

技术标签:

【中文标题】为选择中的每一行调用一个函数 - Postgres【英文标题】:Call a function for each row in select - Postgres 【发布时间】:2015-01-16 19:24:08 【问题描述】:

我有一个名为“getList(date)”的函数。这个函数从参数中输入的日期返回一个项目列表(有几列)。

如果我打电话:

SELECT * FROM getList('12/31/2014');

它工作正常。它返回给我一个包含日期、商品名称和价格的列表。

类似这样的:

date        item_description    price
-----------------------------------------------
12/31/2014      banana          1
12/31/2014      apple           2.5
12/31/2014      coconut         3

但我有另一个表格,其中包含我要搜索的日期。

因此,我想从该表中选择所有日期,并且对于返回的每一行,我想调用我的函数“getList”以获得如下结果:

 date       item_description    price
 -----------------------------------------------
 12/28/2014     banana          0.5
 12/28/2014     apple           1.5
 12/28/2014     coconut         2
 12/31/2014     banana          1
 12/31/2014     apple           2.5
 12/31/2014     coconut         3

我不知道该怎么做。当然我的数据不是水果清单。这只是为了更容易解释整个事情。

非常感谢。

【问题讨论】:

版本? select version() @ClodoaldoNeto 版本是 PostgreSQL 9.2.4 你能改变函数,或者创建另一个接受日期数组作为参数的函数吗?该数组将被取消嵌套并在函数内部连接。它将被称为:select * from getList((select array_agg(the_date) from dates_table)) 【参考方案1】:

正确方式——LATERAL加入

执行此操作的正确方法是使用横向查询(PostgreSQL 9.3 或更高版本):

SELECT d."date", f.item_description, f.price
FROM mydates d,
     LATERAL getList(d."date") f;

见the manual。

传统方式 - SELECT 中的 SRF

在旧版本中,您必须使用带有一些...古怪...属性的 PostgreSQL 扩展,支持SELECT-list 中的集合返回函数。 除非你知道你必须支持 PostgreSQL 9.2 或更早版本,否则不要使用它

SELECT d."date", (getList(d."date").*
FROM mydates d;

这可能会导致对getList 函数进行多次评估,对输出的每一列进行一次。

【讨论】:

传统方式是行之有效的方式。我的 PostgreSQL 版本是 9.2.4,所以 LATERAL JOIN 不起作用。我的 sql 现在太慢了,因为正如你所说,该函数被执行了多次。所以我想我必须找到另一种方法来构建这个 sql。谢谢! @Gilbert 如果将getList(...) 调用包装在另一层子查询中,则可以避免双重评估。我认为在其他先前的答案中有一些例子。我现在没有时间模拟测试用例。

以上是关于为选择中的每一行调用一个函数 - Postgres的主要内容,如果未能解决你的问题,请参考以下文章

对于选择中的每个位置,将多行分组为一个字符串 postgres

为数据框中的每一行应用一个函数,用于另一个数据框中的每一行

将邮政编码 API 调用应用于数据框中的每一行

使用具有不同 order by 子句的 postgres 窗口函数

对 Pandas 数据框中的每一行只运行一次函数

Postgres:如何聚合一行以报告具有最高值的列名?