PostgreSQL中SQL Server CHOOSE与STRING_SPLIT的等效实现及优化迁移
在PostgreSQL中实现类似SQL Server的存储过程优化演进
初始写法(与SQL Server逻辑一致)
select id, 'col1' as valtype, col1 as val from table1 where col1 > 0 union all select id, 'col2', col2 from table1 where col2 > 0 union all select id, 'col3', col3 from table1 where col3 > 0
第一步优化:CROSS JOIN + CASE表达式
PostgreSQL完全支持该逻辑,写法与SQL Server几乎一致:
select * from (select id, valtype, case valtype when 'col1' then col1 when 'col2' then col2 when 'col3' then col3 end as val from table1 cross join (values ('col1'), ('col2'), ('col3')) t(valtype) ) a where val > 0
第二步优化:带序号的字符串拆分 + 位置取值
对应SQL Server中string_split带序号和CHOOSE的用法,PostgreSQL可以通过以下方式实现:
带索引的字符串拆分替代方案
PostgreSQL没有内置返回序号的string_split函数,但可以用string_to_array配合unnest(...) WITH ORDINALITY实现带索引的拆分:
select * from (select id, t.valtype, (array[col1, col2, col3])[t.ordinal] as val from table1 cross join unnest(string_to_array('col1,col2,col3', ',')) WITH ORDINALITY as t(valtype, ordinal) ) a where val > 0
CHOOSE函数的等效实现
PostgreSQL没有内置CHOOSE函数,但可以通过两种方式实现等效逻辑:
- 数组索引法(最简洁,与CHOOSE逻辑对齐):
将目标列放入数组,用拆分得到的ordinal作为索引(PostgreSQL数组默认从1开始计数,与SQL Server CHOOSE的参数逻辑一致),即上述代码中的(array[col1, col2, col3])[t.ordinal]。 - 自定义函数法:如果需要完全贴合CHOOSE的调用形式,可以自定义函数:
使用时与SQL Server完全一致:create function choose(pos int, variadic args anyarray) returns anyelement as $$ begin return args[pos]; end; $$ language plpgsql immutable;select id, t.valtype, choose(t.ordinal, col1, col2, col3) as val from table1 cross join unnest(string_to_array('col1,col2,col3', ',')) WITH ORDINALITY as t(valtype, ordinal) where val > 0
内容的提问来源于stack exchange,提问作者user433342
相关产品推荐
相关产品推荐

