[英]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.您可以将
ListAgg
与case
条件一起使用,仅将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.