如何使用Oracle SQL提取多行列值中等号后指定key对应的取值
Oracle 多行键值对字段查询实现方案
先做前置假设:你的业务表名为biz_table,存储多行键值对的列名为kv_content,表主键为id(可按需替换为实际表名、字段名)。
方案1:直接提取指定Key的对应值(适合单Key查询场景)
直接用正则匹配目标Key,无需全量拆分所有键值对,性能更好:
SELECT 'key01' AS KEY, REGEXP_SUBSTR( kv_content, 'key01=([^'||CHR(10)||']*)', -- 匹配key01=开头到换行符前的内容 1, 1, 'i', -- 不需要区分Key大小写时保留该参数,严格匹配大小写可删除 1 -- 取正则第一个分组结果,即=后的value部分 ) AS VALUE FROM biz_table -- 可选过滤:仅返回存在该Key的行 WHERE REGEXP_LIKE(kv_content, '^key01=|'||CHR(10)||'key01=', 'i');
- 适配说明:如果换行符是Windows格式的回车+换行,把SQL中的
CHR(10)替换为CHR(13)||CHR(10)即可。
方案2:全量拆分键值对后过滤(适合多Key查询、全量遍历场景)
先把每个单元格内的多行键值对拆分为单行,再拆分Key和Value,灵活性更高:
WITH split_kv AS ( -- 拆分每行键值对为独立单行记录 SELECT id, -- 可保留原表主键用于关联其他字段 TRIM(REGEXP_SUBSTR(kv_content, '[^'||CHR(10)||']+', 1, LEVEL)) AS kv_line FROM biz_table CONNECT BY LEVEL <= REGEXP_COUNT(kv_content, CHR(10)) + 1 AND PRIOR id = id AND PRIOR SYS_GUID() IS NOT NULL -- 避免多原行查询时产生笛卡尔积 ), parse_kv AS ( -- 拆分单条键值对为Key、Value两列 SELECT TRIM(REGEXP_SUBSTR(kv_line, '[^=]+', 1, 1)) AS KEY, -- 如果Value中可能包含=号,改用下面的写法取第一个=之后的全部内容作为Value -- SUBSTR(kv_line, INSTR(kv_line, '=') + 1) AS VALUE TRIM(REGEXP_SUBSTR(kv_line, '[^=]+', 1, 2)) AS VALUE FROM split_kv WHERE kv_line IS NOT NULL AND INSTR(kv_line, '=') > 0 -- 过滤不符合键值对格式的无效行 ) SELECT KEY, VALUE FROM parse_kv WHERE KEY = 'key01'; -- 可灵活扩展多Key查询,例如 KEY IN ('key01','key02')
内容的提问来源于stack exchange,提问作者bStk83
相关产品推荐
相关产品推荐

