【问题标题】:Call a function for each row in select - Postgres为选择中的每一行调用一个函数 - 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))

标签: postgresql function postgresql-9.2


【解决方案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(...) 调用包装在另一层子查询中,则可以避免双重评估。我认为在其他先前的答案中有一些例子。我现在没有时间模拟测试用例。
猜你喜欢
  • 2016-04-02
  • 1970-01-01
  • 2011-11-23
  • 1970-01-01
  • 2018-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多