ID Value1 Value2 Value3
A 123 456 789
B 234 567 NULL
我可以使用Regexp_substr来做到这一点
例如
select regexp_substr(Value, '[^,]+', 1) AS Value1,
regexp_substr(Value, '[^,]+', 1, 2) AS Value2,
regexp_substr(Value, '[^,]+', 1, 3) AS Value3
.....
但这要求我知道将来可能会改变的最大价值长度,因此需要添加或删除Regexp_substr语句。
有一种编写此SQL的方法,以便创建的列数基于最大值长度,而不是Regex语句的数量。
,例如,如果我在python中这样做,我只会使用for loop toloop
您无法使用静态SQL语句来做到这一点。 SQL(在所有方言中,不仅是Oracle)需要固定的已知列数,因此您要么需要进行判断调用并生成固定数量的列或修改您的要求。
如果您知道自己将拥有最多3个值,那么您可以使用:
SELECT REGEXP_SUBSTR(value, '(.*?)(,|$)', 1, 1, NULL, 1) AS Value1,
REGEXP_SUBSTR(value, '(.*?)(,|$)', 1, 2, NULL, 1) AS Value2,
REGEXP_SUBSTR(value, '(.*?)(,|$)', 1, 3, NULL, 1) AS Value3
FROM table_name
,对于示例数据,哪个:
输出:
value1
Value2
value3
2 | 3 | |
---|---|---|
如果您想动态生成任何数量的项目的输出,那么这不是SQL设计的。而不是生成值作为列的值,而是将值以行生成:
WITH bounds (value, idx, spos, epos) AS (
SELECT value, 1, 1, INSTR(value, ',', 1)
FROM table_name
UNION ALL
SELECT value, idx + 1, epos + 1, INSTR(value, ',', epos + 1)
FROM bounds
WHERE epos > 0
)
SEARCH DEPTH FIRST BY value SET order_id
SELECT value,
idx,
CASE epos
WHEN 0
THEN SUBSTR(value, spos)
ELSE SUBSTR(value, spos, epos - spos)
END AS item
FROM bounds
|
输出: |
,41
null
1,2,3 | ||