将分隔的单元格记录拆分为行性能



我有 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个解决方案

  1. 我可以分离级别,例如
SELECT COLUMN1,COLUMN2, REGEXP_SUBSTR(COLUMN2,'[^|]d+',1,LEVEL)
FROM TABLE_NAME
CONNECT BY REGEXP_SUBSTR(COLUMN2,'[^|]d+',1,LEVEL) IS NOT NULL
  1. 我可以将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 数据总是一团糟。

最新更新