JOIN on 集合返回函数结果
JOIN on set returning function results
我正在尝试加入 table 并运行 returns 行:
SELECT p.id, p.name, f.action, f.amount
FROM person p
JOIN calculate_payments(p.id) f(id, action, amount) ON (f.id = p.id);
此函数returns 每个 id 0、1 或更多行。
该查询适用于 PostgreSQL 9.3,但在 9.1 上显示以下错误:
ERROR: invalid reference to FROM-clause entry for table "p"
HINT: There is an entry for table "p", but it cannot be referenced from this part of the query
我无法将函数中的计算移出到查询中。
据我所知,我无法使用 JOIN LATERAL 这是 9.3 中的新功能。
这个问题有解决办法吗?
在 Postgres 中 9.1:
SELECT name, (f).* -- note the parentheses!
FROM (SELECT name, calculate_payments(id) AS f FROM person) sub;
假设您的函数具有定义明确的 return 类型和列名称 (id, action, amount)
。并且你的函数总是 return 与它被馈送的 id
相同(这是多余的,可能会被优化)。
相同的 更详细的形式:
SELECT sub.id, sub.name, (sub.f).action, (sub.f).amount -- parentheses!
FROM (
SELECT p.id, p.name, calculate_payments(p.id) AS f(id, action, amount)
FROM person p
) sub;
Set-returning SELECT
列表中的函数会产生多行。但这是一个非标准且有些古怪的功能。 pg 9.3+ 中的新 LATERAL
功能更可取。
您可以在同一步骤中分解行类型:
SELECT *, (calculate_payments(p.id)).* -- parentheses!
FROM person p
但是由于 Postgres 查询规划器的弱点,这将对每个结果列计算一次函数:
- How to avoid multiple function evals with the (func()).* syntax in an SQL query?
或者你的情况:
SELECT p.id, p.name
, (calculate_payments(p.id)).action
, (calculate_payments(p.id)).amount
FROM person p
同样的问题:重复评价
准确地说,pg 9.3+ 中的解决方案等效于此,在结果中保留行,其中函数 returns 0 行:
SELECT p.id, p.name, f.action, f.amount
FROM person p
LEFT JOIN LATERAL calculate_payments(p.id) f ON true;
如果你不关心这个,你可以在pg 9.3+中简化:
SELECT p.id, p.name, f.action, f.amount
FROM person p, calculate_payments(p.id) f;
密切相关:
- Record returned from function has columns concatenated
我正在尝试加入 table 并运行 returns 行:
SELECT p.id, p.name, f.action, f.amount
FROM person p
JOIN calculate_payments(p.id) f(id, action, amount) ON (f.id = p.id);
此函数returns 每个 id 0、1 或更多行。 该查询适用于 PostgreSQL 9.3,但在 9.1 上显示以下错误:
ERROR: invalid reference to FROM-clause entry for table "p" HINT: There is an entry for table "p", but it cannot be referenced from this part of the query
我无法将函数中的计算移出到查询中。
据我所知,我无法使用 JOIN LATERAL 这是 9.3 中的新功能。
这个问题有解决办法吗?
在 Postgres 中 9.1:
SELECT name, (f).* -- note the parentheses!
FROM (SELECT name, calculate_payments(id) AS f FROM person) sub;
假设您的函数具有定义明确的 return 类型和列名称 (id, action, amount)
。并且你的函数总是 return 与它被馈送的 id
相同(这是多余的,可能会被优化)。
相同的 更详细的形式:
SELECT sub.id, sub.name, (sub.f).action, (sub.f).amount -- parentheses!
FROM (
SELECT p.id, p.name, calculate_payments(p.id) AS f(id, action, amount)
FROM person p
) sub;
Set-returning SELECT
列表中的函数会产生多行。但这是一个非标准且有些古怪的功能。 pg 9.3+ 中的新 LATERAL
功能更可取。
您可以在同一步骤中分解行类型:
SELECT *, (calculate_payments(p.id)).* -- parentheses!
FROM person p
但是由于 Postgres 查询规划器的弱点,这将对每个结果列计算一次函数:
- How to avoid multiple function evals with the (func()).* syntax in an SQL query?
或者你的情况:
SELECT p.id, p.name
, (calculate_payments(p.id)).action
, (calculate_payments(p.id)).amount
FROM person p
同样的问题:重复评价
准确地说,pg 9.3+ 中的解决方案等效于此,在结果中保留行,其中函数 returns 0 行:
SELECT p.id, p.name, f.action, f.amount
FROM person p
LEFT JOIN LATERAL calculate_payments(p.id) f ON true;
如果你不关心这个,你可以在pg 9.3+中简化:
SELECT p.id, p.name, f.action, f.amount
FROM person p, calculate_payments(p.id) f;
密切相关:
- Record returned from function has columns concatenated