我有 2 列
COLUMN1 || COLUMN2
15 || 23|45|65|44|66|15
34 || 45|21|16|34|79
我想将COLUMN2
区分为行,并与一些特殊的语法合并,例如$0:15$1:23$1:45$1:65$1:44$1:66
。要解决这个问题,这里有2个解决方案
- 我可以分离级别,例如
SELECT COLUMN1,COLUMN2, REGEXP_SUBSTR(COLUMN2,'[^|]d+',1,LEVEL)
FROM TABLE_NAME
CONNECT BY REGEXP_SUBSTR(COLUMN2,'[^|]d+',1,LEVEL) IS NOT NULL
- 我可以将
COLUMN2
分离到其他列并将其合并回来。但这会产生很多regexp_substr
功能。
问题在这里,我对性能产生了巨大的影响。花了这么长时间。我正在寻找更有效的方法。超过1M
的行计数。
编辑 1 :COLUMN1 将作为$0:
开始,如果COLUMN2在分隔中具有相同的值,则不会在结果中考虑它。
预期输出 :
$0:15$1:23$1:45$1:65$1:44$1:66
$0:34$1:45$1:21$1:16$1:79
请注意,列 1 不能是列 2 的第一个元素
我可能是错的,但它看起来像一个简单的替换案例,如下所示:
SELECT '$0:' || REPLACE('23|45|65|44|66','|',' $1:') FROM DUAL;
如果您需要其他任何内容,请发表评论。
--更新--
根据问题中添加的附加条件,您现在可以尝试:
SQL> WITH MY_TAB(COL1,COL2)
2 AS (
3 SELECT 15, '23|45|65|44|66|15' FROM DUAL UNION ALL
4 SELECT 34, '45|21|16|34|79' FROM DUAL
5 )SELECT
6 '$0:'
7 || COL1
8 || '$1:'
9 || REPLACE(REPLACE(COL2, '|' || COL1, ''), '|', '$1:') AS DESIRED_VALUE
10 FROM
11 MY_TAB;
DESIRED_VALUE
--------------------------------------------------------------------------------
$0:15$1:23$1:45$1:65$1:44$1:66
$0:34$1:45$1:21$1:16$1:79
SQL>
干杯!!
可以使用以下语法生成预期结果:
RTRIM('$0'|| column1 ||
REPLACE( '$1:' || REPLACE(column2,'|',' $1:') || '$'
, '$1:'||column1||'$'
, '$')
,'$')
您也可以使用递归查询代替原始查询,从而删除重复的行:
WITH TABLE_NAME (column1, column2) AS (
select 15 , '23|45|65|44|66' from dual UNION all
select 34 , '45|21|16|95|79' from dual)
, rec (column1, pos, col2, column2) AS (
SELECT column1, 1, REGEXP_SUBSTR(COLUMN2,'d+'), column2 FROM table_name
UNION ALL
SELECT column1, pos + 1, REGEXP_SUBSTR(COLUMN2,'d+',1,pos + 1), column2
FROM rec
WHERE REGEXP_SUBSTR(COLUMN2,'d+',1,pos + 1) IS NOT NULL )
SELECT * FROM rec
我建议创建一个新表并在那里拆分 csv 列以获得更好的数据模型,然后对该数据进行所有遗漏会更容易。处理 csv 数据总是一团糟。