PostgreSQL 8.3中整合表函数结果到主查询的替代方案
解决PostgreSQL 8.3中无法使用LATERAL关联表函数的问题
首先明确问题根源:PostgreSQL 8.3不支持LATERAL关键字——这个特性是在9.3版本才被引入的,所以你用LATERAL关联表函数的写法必然会报错,这是版本限制导致的。
针对你的场景,这里给出几种可行的替代实现方案:
方案1:将表函数调用放到SELECT列表中
因为你的函数总是返回单行结果,所以可以直接在SELECT子句中调用它,还能按需展开返回的列:
如果只是需要执行函数(比如函数内部有业务逻辑要触发)同时获取主表ID:
SELECT t.id FROM t_events AS t WHERE t.id = 20170913;
如果需要同时获取函数返回的三个列值:
-- 展开所有列的简洁写法 SELECT t.id, (get_event_deposit_values(t.id, '1999/01/01', '2018/05/11')).* FROM t_events AS t WHERE t.id = 20170913; -- 或者指定单个列 SELECT t.id, (get_event_deposit_values(t.id, '1999/01/01', '2018/05/11')).carried_over, (get_event_deposit_values(t.id, '1999/01/01', '2018/05/11')).current_month, (get_event_deposit_values(t.id, '1999/01/01', '2018/05/11')).deposit FROM t_events AS t WHERE t.id = 20170913;
这种方式能正常引用主表的t.id作为函数参数,因为SELECT子句的表达式是在FROM子句的表扫描之后执行的。
方案2:将函数逻辑内联到主查询
如果你的函数逻辑不算复杂(比如当前示例只是初始化三个0值返回),可以直接把函数里的逻辑写到主查询中,避免调用表函数:
SELECT t.id, 0 AS carried_over, 0 AS current_month, 0 AS deposit FROM t_events AS t WHERE t.id = 20170913;
如果函数实际有更复杂的逻辑(比如关联其他表计算值),也可以把那部分逻辑改写成子查询或关联查询直接整合到主SQL里。
方案3:用标量子查询过滤或取值
如果只需要函数返回的单个值(比如用来做过滤条件),可以用标量子查询的方式:
SELECT t.id FROM t_events AS t WHERE (SELECT carried_over FROM get_event_deposit_values(t.id, '1999/01/01', '2018/05/11')) = 0 AND t.id = 20170913;
额外建议
PostgreSQL 8.3是2008年发布的超老旧版本,早就停止了官方支持,不仅功能受限,还存在潜在的安全漏洞。如果条件允许,强烈建议升级到较新的稳定版本(比如12+或最新版),这样能使用包括LATERAL在内的大量现代特性,也能获得持续的安全更新。
内容的提问来源于stack exchange,提问作者M. Ko
相关产品推荐
相关产品推荐

