在oracle中将一行拆分为多个

时间:2018-07-26 06:24:39

标签: database oracle select view

我有一个表,其中包含如下数据:

{
    "queryType": "scan",
    "dataSource": "xyz",
    "resultFormat": "list",
    "columns": ["test_station_name", "station_id", "result", "mac_address"],
    "intervals": ["2018-01-01/2018-02-09"],
    "filter": {
        "type": "selector",
        "dimension": "sn",
        "value": "GH6747246T4JLR6AZ"
    }
}

现在,如果我们从该表中选择数据,它将得到如下结果:

CREATE TABLE UDA_DATA 
( uda VARCHAR2(20), 
value_text VARCHAR2(4000) 
); 
insert into UDA_DATA values('Material_ID','PBL000129 PBL000132 PBL000130 PBL000131 PBL000133'); 
insert into UDA_DATA values('Material_ID','PBL000134 PBL000138 PBL000135 PBL000136 PBL000137'); 
insert into UDA_DATA values('Material_ID','PBL000125 PBL000128 PBL000126 PBL000124 PBL000127'); 
commit;

它给出如下结果: Present result

但是我期待这样的事情: Expected Result

意味着如果字符长度超过30,则select * from UDA_DATA; 应该分成两行或更多行。而且,uda列的后缀应为1,2..n

不确定如何在选择查询中实现这一目标。

1 个答案:

答案 0 :(得分:0)

您可以使用recursive subquery factoring

with rcte (uda, value, chunk_num, value_text) as (
  select uda,
    substr(value_text, 1, 30),
    1,
    substr(value_text, 31)
  from uda_data
  union all
  select uda,
    substr(value_text, 1, 30),
    chunk_num + 1,
    substr(value_text, 31)
  from rcte
  where value_text is not null
)
select uda || chunk_num as uda, value
from rcte;

UDA                  VALUE                                   
-------------------- ----------------------------------------
Material_ID1         PBL000129 PBL000132 PBL000130           
Material_ID1         PBL000134 PBL000138 PBL000135           
Material_ID1         PBL000125 PBL000128 PBL000126           
Material_ID2         PBL000131 PBL000133                     
Material_ID2         PBL000136 PBL000137                     
Material_ID2         PBL000124 PBL000127                     

锚点成员使用substr来获取前30个字符作为值,并为锚点设置始终为1的块号。在删除了前30个字符后,它还会获取字符串的剩余部分,该字段可以为null。

递归成员的功能完全相同,但是从字符串的其余部分开始工作(如上一次迭代所找到的那样),并增加块的数量。

最后,主查询只获取所有提取的块,并将块编号附加到uda字符串中。

如果有唯一键,则可以使用分层查询-显示的数据虽然没有。


您的样本数据没有任何有用的结果排序依据。如果您的真实表具有唯一键,则可以通过将其包含在递归CTE的两个分支中,然后将其添加到最终结果中来使用它

order by unique_key, chunk_num

如果没有打开,则可以通过在锚成员中引入虚拟密钥来接近预期结果,例如使用row_number()或更简单的rownum

with rcte (rn, uda, value, chunk_num, value_text) as (
  select rownum,
    uda,
    substr(value_text, 1, 30),
    1,
    substr(value_text, 31)
  from uda_data
  union all
  select rn,
    uda,
    substr(value_text, 1, 30),
    chunk_num + 1,
    substr(value_text, 31)
  from rcte
  where value_text is not null
)
select uda || chunk_num as uda, value
from rcte
order by rn, chunk_num;

UDA                  VALUE                                   
-------------------- ----------------------------------------
Material_ID1         PBL000129 PBL000132 PBL000130           
Material_ID2         PBL000131 PBL000133                     
Material_ID1         PBL000134 PBL000138 PBL000135           
Material_ID2         PBL000136 PBL000137                     
Material_ID1         PBL000125 PBL000128 PBL000126           
Material_ID2         PBL000124 PBL000127