您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

将函数返回的记录拆分为多列

将函数返回的记录拆分为多列

在Postgres 或更高版本中,最好通过联接来解决LATERAL

SELECT *
FROM   actors a 
JOIN   movies_actors ma on a.actor_id = ma.movie_id 
LEFT   JOIN LATERAL hi_lo(a.actor_id, length(a.name), ma.movie_id) x ON true
LIMIT  10;

避免重复评估函数(对于输出中的每一列-必须以任何一种方式为每个输入行调用函数)。LEFT JOIN LATERAL ... ON true如果函数不返回行,则避免从左侧删除

在您的评论中进行跟进:

仅由函数调用产生的扩展列

SELECT x.*  -- that's all!
FROM   actors a 
JOIN   movies_actors ma on a.actor_id = ma.movie_id 
LEFT   JOIN LATERAL hi_lo(a.actor_id, length(a.name), ma.movie_id) x ON true
LIMIT  10;

但是,由于您不关心其他列,因此可以简化为:

SELECT x.*
FROM   actors a 
JOIN   movies_actors ma on a.actor_id = ma.movie_id 
     , hi_lo(a.actor_id, length(a.name), ma.movie_id) x
LIMIT  10;

这是一个隐式的CROSS JOIN LATERAL。如果函数实际上偶尔会返回“ no row”,则结果可能会有所不同:我们没有为这些行获取NULL值,这些行被消除了- LIMIT不再计数。

在 (或通常),您也可以使用正确的语法来分解复合类型:

SELECT *, **(** hi_lo(a.actor_id, length(a.name), ma.movie_id) **).***  -- note extra parentheses!
FROM   actors a 
JOIN   movies_actors ma on a.actor_id = ma.movie_id 
LIMIT  10;

缺点是由于Postgres查询计划程序的弱点,该函数函数输出中的每一列都进行了一次评估。最好将调用移到子查询或CTE中,并在外部分解行类型SELECT。喜欢:

SELECT actor_id, movie_id, (x).*  -- explicit column names for the rest
FROM  (
   SELECT *, hi_lo(a.actor_id, length(a.name), ma.movie_id) AS x
   FROM   actors a 
   JOIN   movies_actors ma on a.actor_id = ma.movie_id 
   LIMIT  10
   ) sub;

但是,您必须命名单个列,SELECT *除非您对结果中的行类型有多余的理解,否则您将无法避免。

其他 2022/1/1 18:27:47 有459人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶