SQL-将单个列拆分为多行
我在数据库中有一个类似的记录(作为示例) 我需要导出数据并创建多个记录,其中Brand有多个条目。我还需要增加输出上的ID,这样就不会有重复项。(我可以为此使用序列,并将其设置为更高的最大值(以db为单位) 我的输出看起来像SQL-将单个列拆分为多行,sql,oracle,Sql,Oracle,我在数据库中有一个类似的记录(作为示例) 我需要导出数据并创建多个记录,其中Brand有多个条目。我还需要增加输出上的ID,这样就不会有重复项。(我可以为此使用序列,并将其设置为更高的最大值(以db为单位) 我的输出看起来像 ID, Name, Brand 1, Bike, Schwinn 2, Car, Ford Sequence.nextval, Car, Honda Sequence.nextval, Car, Chevy 3, Bike, Schwinn Sequence.nextval
ID, Name, Brand
1, Bike, Schwinn
2, Car, Ford
Sequence.nextval, Car, Honda
Sequence.nextval, Car, Chevy
3, Bike, Schwinn
Sequence.nextval, Bike, Trex
4, Car, Honda
我想尝试用SQL
语句来解释这一点。基本上,我通过straightSQL
将这些数据作为csv
文件转储
我的困难是试图通过品牌栏
循环/拆分。您可以使用以下select语句:
with test_tab (ID, Name, Brand) as (
select 1, 'Bike', 'Schwinn' from dual union all
select 2, 'Car', 'Ford, Honda, Chevy' from dual union all
select 3, 'Bike', 'Schwinn, Trex' from dual union all
select 4, 'Car', 'Honda' from dual)
--------------------
-- End of Data Preparation
--------------------
select case when level <> 1 then <your_sequece>.nextval else id end as id,
name,
trim(regexp_substr(Brand, '[^,]+', 1, level)) BRAND
from test_tab
connect by regexp_substr(Brand, '[^,]+', 1, level) is not null
and prior Brand = Brand
and prior sys_guid() is not null;
您可以将Insert语句编写为
Insert into <destination_table>
select case when level <> 1 then <your_sequece>.nextval else id end as id,
name,
trim(regexp_substr(Brand, '[^,]+', 1, level)) BRAND
from <source_table>
connect by regexp_substr(Brand, '[^,]+', 1, level) is not null
and prior Brand = Brand
and prior sys_guid() is not null;
谢谢,桑,很棒的东西。不幸的是,它不能完全工作,因为我有重复品牌的记录,例如1,‘汽车’、‘福特、本田、雪佛兰’,记录2=2,‘卡车’、‘福特、本田、,雪佛兰“它似乎陷入了某种循环,我用和previous ID=ID
替换了大量的recordsTry,因为它的ID在源数据中似乎是唯一的。我已经修改了答案。这类问题是一个完美的例子,说明了为什么逗号分隔字段是一个坏主意,而数据库规范化很重要。
ID NAME BRAND
---------------------
2 Car Ford
5 Car Honda
6 Car Chevy
4 Car Honda
1 Bike Schwinn
3 Bike Schwinn
7 Bike Trex
Insert into <destination_table>
select case when level <> 1 then <your_sequece>.nextval else id end as id,
name,
trim(regexp_substr(Brand, '[^,]+', 1, level)) BRAND
from <source_table>
connect by regexp_substr(Brand, '[^,]+', 1, level) is not null
and prior Brand = Brand
and prior sys_guid() is not null;
select case when level <> 1 then <your_sequece>.nextval else id end as id,
name,
trim(regexp_substr(Brand, '[^,]+', 1, level)) BRAND
from <source_table>
connect BY regexp_substr(Brand, '[^,]+', 1, level) is not null
and prior ID = ID
and prior sys_guid() is not null;