Oracle的SQL将文本分为行并进行过滤

时间:2019-06-11 17:04:18

标签: sql regex oracle

我在表行中存储了多行文本数据,例如此处的模拟示例。有些行被标记为“重要”,我试图选择所有“重要”行的列表以及相应的ID。

 select 10001 as id, 'some random text 11
 more random text IMPORTANT 12
 more random text IMPORTANT 13' as str
   from dual
  union all
 select 10002, 'other random text 21
 other random text IMPORTANT 22
 other random text 23'
   from dual;

我需要这样的东西...

id      important text
10001   more random text IMPORTANT 12
10001   more random text IMPORTANT 13
10002   other random text IMPORTANT 22

我希望在单个SELECT中做到这一点,而没有任何临时表或游标,而且我一直在使用带有查询连接的regexp_substr进行查找,但似乎被卡住了。您的帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

您可以执行以下操作...不确定外部查询中的WHERE条件,您可以根据需要进行调整(我允许IMPORTANT以任何大写字母出现,并且我不要求将它作为大写字母单个词-例如,它可能是“不重要”一词的一部分,但您必须对此进行修正),但我认为这并不是您要问的主要问题。子查询确实解决了“主要问题”。

WITH子句当然不是解决方案的一部分(SELECT查询);只能提供测试数据。

了解'm'修饰符(用于“多行”)-它允许^和$匹配每行文本的开头和结尾,而不是默认值(即文本的开头和结尾)整个字符串,而不考虑换行符)。

with
  test_data as (
     select 10001 as id, 'some random text 11
more random text IMPORTANT 12
more random text IMPORTANT 13' as str
   from dual
  union all
 select 10002, 'other random text 21
other random text IMPORTANT 22
other random text 23'
   from dual
)
select *
from   (
         select     id, regexp_substr(str, '^.*$', 1, level, 'm') as str_line
         from       test_data
         connect by level <= regexp_count(str, '^.*$', 1, 'm')
                and prior id =  id
                and prior sys_guid() is not null
       )
where upper(str_line) like '%IMPORTANT%'   -- modify this as needed
;

   ID  STR_LINE                        
-----  --------------------------------
10001  more random text IMPORTANT 12   
10001  more random text IMPORTANT 13   
10002  other random text IMPORTANT 22