Teradata用STRTOK_SPLIT_TO_TABLE拆分字段为多行语法报错如何解决
解决方案
报错原因
你原有SQL的语法不符合表函数的调用规则:支持strtok_split_to_table这类拆分函数的数据库,都需要用CROSS JOIN(或LATERAL JOIN)关联拆分生成的虚拟表,不能直接把函数写在原表名后面。另外你定义的token长度只有20,会截断你字段里的长内容,需要调大长度。
方法1:修正原有函数写法(适用于支持strtok_split_to_table的数据库,如Teradata)
直接修正语法即可运行:
SELECT d.* FROM Audit as t CROSS JOIN strtok_split_to_table(t.ID, t.CONTENT, '</b>') RETURNS (outkey integer, tokennum integer, token varchar(1000) character set unicode) as d ORDER BY outkey, tokennum;
方法2:通用递归CTE实现(无数据库依赖,逻辑易懂,新手推荐)
不需要依赖数据库特有的拆分函数,绝大多数主流数据库都支持该写法,逻辑就是逐层查找分隔符位置,逐段切割内容直到全部拆分完成:
WITH RECURSIVE split_content AS ( -- 初始层:切割第一段内容,保留剩余未切割的内容 SELECT ID, 1 AS tokennum, -- 截取第一个</b>之前的内容作为第一个token SUBSTRING(CONTENT, 1, INSTR(CONTENT, '</b>') - 1) AS token, -- 保存第一个</b>之后的内容,留到下一轮切割 SUBSTRING(CONTENT, INSTR(CONTENT, '</b>') + LENGTH('</b>')) AS remaining_content FROM Audit WHERE CONTENT IS NOT NULL AND INSTR(CONTENT, '</b>') > 0 UNION ALL -- 递归层:循环切割剩余内容 SELECT ID, tokennum + 1 AS tokennum, SUBSTRING(remaining_content, 1, INSTR(remaining_content, '</b>') - 1) AS token, SUBSTRING(remaining_content, INSTR(remaining_content, '</b>') + LENGTH('</b>')) AS remaining_content FROM split_content -- 剩余内容还有</b>就继续切割,没有就停止 WHERE INSTR(remaining_content, '</b>') > 0 ) -- 查询最终拆分结果 SELECT ID, tokennum, token FROM split_content ORDER BY ID, tokennum;
优化提示
- 拆分出来的token会携带多余的
<b>标签、空格、<br>标签,你可以用REPLACE、TRIM函数清理,示例:REPLACE(REPLACE(TRIM(token), '<b>', ''), '<br/>', '') - 你的字段里有连续的
</b></b>,拆分后会生成空token,可以在最终查询时加WHERE TRIM(token) <> ''过滤空行 - 如果需要保留最后一段没有
</b>的剩余内容,可以在最终查询前加一段UNION ALL查询递归最后剩下的remaining_content字段即可。
内容的提问来源于stack exchange,提问作者Tekno Joe
相关产品推荐
相关产品推荐

