将Oracle循环式自定义ASCII值计算转为PostgreSQL集合式实现
PostgreSQL集合式实现方案
以下是不使用循环或游标,纯集合查询实现的代码,完全匹配预期输出94874704955518361:
SELECT string_agg(processed_str, '')::bigint AS final_result FROM ( SELECT ordinality AS pos, CASE WHEN ch BETWEEN 'A' AND 'Z' THEN CASE ch WHEN 'S' THEN (ASCII(ch) + 11)::text WHEN 'T' THEN (ASCII(ch) + 3)::text WHEN 'A' THEN (ASCII(ch) - 18)::text WHEN 'C' THEN LPAD((ASCII(ch) - 63)::text, 2, '0') -- 补前导0确保为两位 WHEN 'K' THEN (ASCII(ch) + 20)::text END WHEN ch BETWEEN '0' AND '9' THEN CASE WHEN ch = '1' AND ordinality = 6 THEN (ASCII(ch) + 6)::text WHEN ch = '1' AND ordinality = 8 THEN (ASCII(ch) + 312)::text WHEN ch = '0' THEN (ASCII(ch) - 30)::text END END AS processed_str FROM string_to_table('STACK101', NULL) WITH ORDINALITY AS t(ch, ordinality) ) AS char_processing ORDER BY pos;
代码说明
- 字符串拆分:使用
string_to_table(..., NULL) WITH ORDINALITY将输入字符串拆分为带位置索引的单个字符集合,替代Oracle中的循环遍历逻辑。 - ASCII值条件运算:通过嵌套
CASE语句复现原代码中基于ASCII值的加减规则,对不同字符和位置执行对应计算,其中LPAD用于确保字符C的处理结果为两位字符串(补前导0)。 - 结果拼接与转换:使用
string_agg按字符位置顺序拼接所有处理后的字符串片段,最后转换为bigint类型得到最终数值。
执行上述查询后,将直接返回预期结果:94874704955518361。
内容的提问来源于stack exchange,提问作者MAK
相关产品推荐
相关产品推荐

