简体   繁体   English

PL sql子字符串问题

[英]PL sql substring issue

I have a column as below.我有一个专栏如下。 there are multiple columns like this with different data.有多个这样的列具有不同的数据。 在此处输入图像描述

I need output like this我需要这样的输出

在此处输入图像描述

I need values that inside |我需要内在的价值观 | | | symbols.符号。 I tried like below But not successes.我尝试如下但没有成功。 I am new to PL SQL.我是 PL SQL 的新手。 Please give some suggestions to this.请对此提出一些建议。 Do i need a cursor or loop for do this我是否需要一个光标或循环来执行此操作

SELECT 
           regexp_substr(profile_value,'\|([^|]+)\|',1,1,NULL,1) 
FROM table1

As a result of my query i am getting only WO_NO=1^由于我的查询,我只得到WO_NO=1^

This is how I understood it.我是这样理解的。

SQL> with
  2  test (col) as
  3    (select '9D49|WO_NO=1^|WO no: 1;D972|WO_NO=60003^|WO no: 60003;AED1' from dual union all
  4     select '1234|WO_NO=25^|WO no:25;797|WO_NO=26^'                      from dual
  5    ),
  6  temp as
  7    (select regexp_substr(col, '[^|]+', 1, column_value) val,
  8            column_value cv,
  9            col
 10     from test cross join
 11       table(cast(multiset(select level from dual
 12                           connect by level <= regexp_count(col, '\|') + 1
 13                          ) as sys.odcinumberlist))
 14    )
 15  select listagg(val, ' or ') within group (order by cv) result
 16  from temp
 17  where substr(val, 1, 5) = 'WO_NO'
 18  group by col ;

RESULT
--------------------------------------------------------------------------------
WO_NO=25^ or WO_NO=26^
WO_NO=1^ or WO_NO=60003^

SQL>

Splitting the string into items将字符串拆分为项目

Assuming for now that Table1 has a single row, you can write a recursive query and a regular expression to split the string in a single select.现在假设 Table1 有一行,您可以编写一个递归查询和一个正则表达式来将字符串拆分为单个选择。

level denotes the level of recursion. level表示递归的级别。 regexp_substr lets you specify the occurrence in the string. regexp_substr允许您指定字符串中的出现。 connect by provides the exit condition: taking the next item, until there is none. connect by提供退出条件:取下一项,直到没有。

select
  level as ItemNr,
  regexp_substr(profile_value, '[^|]+', 1, level) as Item 
from
  Table1
connect by
  regexp_substr(profile_value, '[^|]+', 1, level) is not null

Combining the wanted items into a new string将想要的项目组合成一个新字符串

You could use ListAgg with a case condition, to combine only the items where level is an even number back into a single string, with the string ' or ' as a separator.您可以将ListAggcase条件一起使用,仅将level为偶数的项目组合回单个字符串,并使用字符串' or '作为分隔符。

select
  listagg(
    case when mod(level, 2) = 0 then
      regexp_substr(profile_value, '[^|]+', 1, level)
    end, ' or ') as Items 
from
  Table1
connect by
  regexp_substr(profile_value, '[^|]+', 1, level) is not null

For multiple rows对于多行

The query above doesn't work well by itself if Table1 has multiple rows.如果 Table1 有多行,上面的查询本身就不能很好地工作。 It assumes a single input value.它假定一个输入值。 Using yet another trick, cross apply , you can make this a subquery that does this transformation for each of the rows of your table.使用另一个技巧cross apply ,您可以使它成为一个子查询,对表的每一行进行这种转换。

The query below shows the original profile_value column, and the transformed items for each of the rows in Table1.下面的查询显示了原始profile_value列,以及 Table1 中每一行的转换items

select
  t.*, x.*
from
  Table1 t
  cross apply (
    select
      listagg(
        case when mod(level, 2) = 0 then
          regexp_substr(profile_value, '[^|]+', 1, level)
        end, ' or ') as Items
    from 
      dual -- just selecting a single profile_value
    connect by
      regexp_substr(profile_value, '[^|]+', 1, level) is not null
  ) x

In the end this works okay for a not to large set of data, but you're storying structured data into a string, and querying this is not very efficient.最后,这适用于不是很大的数据集,但是您将结构化数据存储为字符串,并且查询效率不是很高。

If you need to repeat this query a lot, and the number of rows in Table1 is growing, it's probably better to store it in a more structured way.如果您需要大量重复此查询,并且 Table1 中的行数正在增长,那么以更有条理的方式存储它可能会更好。 If this data is coming from an external source, you could dump it in a temporary table, and transform it using the queries of this answer, to write it to a final, better structured table (or tables) for repeated use.如果此数据来自外部源,您可以将其转储到临时表中,并使用此答案的查询对其进行转换,以将其写入最终的、结构更好的表(或多个表)以供重复使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM