gpt4 book ai didi

sql - 如何将逗号分隔的值转换为oracle中的行?

转载 作者:行者123 更新时间:2023-12-04 09:23:44 25 4
gpt4 key购买 nike

这是 DDL——

create table tbl1 (
id number,
value varchar2(50)
);

insert into tbl1 values (1, 'AA, UT, BT, SK, SX');
insert into tbl1 values (2, 'AA, UT, SX');
insert into tbl1 values (3, 'UT, SK, SX, ZF');

注意,这里的值为 逗号分隔 字符串。

但是,我们需要如下结果-
ID VALUE
-------------
1 AA
1 UT
1 BT
1 SK
1 SX
2 AA
2 UT
2 SX
3 UT
3 SK
3 SX
3 ZF

我们如何为此编写 SQL?

最佳答案

我同意这是一个非常糟糕的设计。
如果您无法更改该设计,请尝试以下操作:

select distinct id, trim(regexp_substr(value,'[^,]+', 1, level) ) value, level
from tbl1
connect by regexp_substr(value, '[^,]+', 1, level) is not null
order by id, level;

输出
id value level
1 AA 1
1 UT 2
1 BT 3
1 SK 4
1 SX 5
2 AA 1
2 UT 2
2 SX 3
3 UT 1
3 SK 2
3 SX 3
3 ZF 4

this

以更优雅和有效的方式删除重复项(感谢@mathguy)
select id, trim(regexp_substr(value,'[^,]+', 1, level) ) value, level
from tbl1
connect by regexp_substr(value, '[^,]+', 1, level) is not null
and PRIOR id = id
and PRIOR SYS_GUID() is not null
order by id, level;

如果您想要“ANSIer”方法,请使用 CTE:
with t (id,res,val,lev) as (
select id, trim(regexp_substr(value,'[^,]+', 1, 1 )) res, value as val, 1 as lev
from tbl1
where regexp_substr(value, '[^,]+', 1, 1) is not null
union all
select id, trim(regexp_substr(val,'[^,]+', 1, lev+1) ) res, val, lev+1 as lev
from t
where regexp_substr(val, '[^,]+', 1, lev+1) is not null
)
select id, res,lev
from t
order by id, lev;

输出
id  val lev
1 AA 1
1 UT 2
1 BT 3
1 SK 4
1 SX 5
2 AA 1
2 UT 2
2 SX 3
3 UT 1
3 SK 2
3 SX 3
3 ZF 4

MT0 的另一种递归方法,但没有正则表达式:
WITH t ( id, value, start_pos, end_pos ) AS
( SELECT id, value, 1, INSTR( value, ',' ) FROM tbl1
UNION ALL
SELECT id,
value,
end_pos + 1,
INSTR( value, ',', end_pos + 1 )
FROM t
WHERE end_pos > 0
)
SELECT id,
SUBSTR( value, start_pos, DECODE( end_pos, 0, LENGTH( value ) + 1, end_pos ) - start_pos ) AS value
FROM t
ORDER BY id,
start_pos;

我尝试了 3 种方法,使用 30000 行数据集和 118104 行返回,并得到以下平均结果:
  • 我的递归方法:5 秒
  • MT0 进场:4 秒
  • Mathguy 方法:16 秒
  • MT0 递归方法无正则表达式:3.45 秒

  • @Mathguy 还使用更大的数据集进行了测试:

    In all cases the recursive query (I only tested the one with regular substr and instr) does better, by a factor of 2 to 5. Here are the combinations of # of strings / tokens per string and CTAS execution times for hierarchical vs. recursive, hierarchical first. All times in seconds


  • 30,000 x 4:5/1。
  • 30,000 x 10:15/3。
  • 30,000 x 25:56/37。
  • 5,000 x 50:33/14。
  • 5,000 x 100:160/81。
  • 10,000 x 200:1,924/772
  • 关于sql - 如何将逗号分隔的值转换为oracle中的行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38371989/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com