SQL不创建自定义函数实现列内字符串拆分生成结构化视图
实现方案
你的两步思路完全可行,不需要自定义函数,用SQL原生的表值拆分函数+字符串提取函数就能实现,全程无UDF,核心逻辑分两步:
- 按
$ $分隔符把raw字段的多产品拼接串拆分为多行,每行对应单个产品的完整属性串,同时保留原表的id字段 - 从单产品属性串中提取六个固定键的对应值,映射为独立列。这里优先用正则按键名提取,比二次拆分按位置取列兼容性更好,不会因为键值对顺序错乱导致值匹配错误。
可直接运行的SQL示例
以下代码适配MySQL 8.0+,其他数据库仅需替换多产品串拆分为多行的表函数即可,列提取逻辑通用:
WITH single_product AS ( SELECT p.id, TRIM(t.prod_str) AS prod_attr_full FROM products p -- 按'$ $'拆分多产品串为多行 -- PostgreSQL/Spark SQL 替换下方JOIN逻辑为: LATERAL SPLIT_TO_TABLE(p.raw, '$ $') t(prod_str) -- BigQuery 替换为: LEFT JOIN UNNEST(SPLIT(p.raw, '$ $')) t(prod_str) JOIN JSON_TABLE( CONCAT('["', REPLACE(p.raw, '$ $', '","'), '"]'), '$[*]' COLUMNS (prod_str TEXT PATH '$') ) t ) SELECT id, REGEXP_SUBSTR(prod_attr_full, 'Description=([^;]+)', 1, 1, NULL, 1) AS Description, REGEXP_SUBSTR(prod_attr_full, 'Cost=([^;]+)', 1, 1, NULL, 1) AS Cost, REGEXP_SUBSTR(prod_attr_full, 'Saving=([^;]+)', 1, 1, NULL, 1) AS Saving, REGEXP_SUBSTR(prod_attr_full, 'ER=([^;]+)', 1, 1, NULL, 1) AS ER, REGEXP_SUBSTR(prod_attr_full, 'EnR=([^;]+)', 1, 1, NULL, 1) AS EnR, REGEXP_SUBSTR(prod_attr_full, 'Eligible=([^;]+)', 1, 1, NULL, 1) AS Eligible FROM single_product;
优化说明
- 正则提取方案不要求键值对的固定顺序,哪怕单产品串里的属性顺序打乱,也能准确匹配到对应键的值,鲁棒性远高于按拆分后固定索引取列的写法
- 如果你的数据里所有产品的键值对顺序完全固定,也可以把正则提取部分替换为二次拆分按索引取值,性能会有小幅提升,以BigQuery为例写法如下:
SELECT id, SPLIT(prod_attr_full, ';')[SAFE_OFFSET(0)] AS Description, SPLIT(prod_attr_full, ';')[SAFE_OFFSET(1)] AS Cost, SPLIT(prod_attr_full, ';')[SAFE_OFFSET(2)] AS Saving, SPLIT(prod_attr_full, ';')[SAFE_OFFSET(3)] AS ER, SPLIT(prod_attr_full, ';')[SAFE_OFFSET(4)] AS EnR, SPLIT(prod_attr_full, ';')[SAFE_OFFSET(5)] AS Eligible FROM single_product
- 最终输出行数和预期一致:id=132返回2行,id=497返回3行,总计5行数据,每行对应一个独立产品。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

