sql - 具有多个值的 REGEXP_INSTR
问题描述
例如,我有两个表 A 和 B
一个
The <number> 1 </number> is cat
The <number> 2 </number> is dog
The <number> 3 </number> is horse
The <number> 4 </number> is chicken
The <number> 5 </number> is hippo
'''
乙
<id>2</id>
<id>4</id>
<id>1</id>
我想将 B 中的值(仅限数字)与表 A 中的所有值交叉检查并得到结果:
is dog
is chicken
is cat
我在“where”查询的部分这样做(只是一个例子):
where (REGEXP_INSTR ((DBMS_LOB.SUBSTR(regexp_substr(A, '<number>(.**?)(\s)'))) , (DBMS_LOB.SUBSTR((select regexp_substr(B, '<id>(.*?)</id>.*',1,1,null,1) from B
FETCH NEXT 1 ROWS ONLY ))))>0;
我的问题是“FETCH NEXT 1 ROWS ONLY”只返回一行,没有它我收到错误“ORA-01427:单行子查询返回多行”(逻辑)。如何将 B 中的所有数字与 A 中的所有行进行比较并接收 3 个结果?
非常感谢
更新 19/10
下面是更准确的信息。
select col1
from
(select regexp_substr(B.E, '<InternalId>(.**?)(\s)') as col1, (select regexp_substr(table_D.data1, '<InternalId>(.*?)</InternalId>.*',1,1,null,1) from table_F D) as col2
from table_C B
where table_B.E like 'xxxxx')
where REGEXP_INSTR ((DBMS_LOB.SUBSTR(col1)) , (DBMS_LOB.SUBSTR(col2)))>0;
table_D.data1 是这样的:
<?xml version="1.0"?>
<FVDeliveryAdvice>
<Header>
<InternalId>2</InternalId>
<Datatype>200</Datatype>
</Header>
<Item>
<Subitem>
</Subitem>
</Item>
</FVDeliveryAdvice>
和
像那样
----- PL/SQL Error Message -----
<InternalId>2</InternalId>ORA-20104: ALR not found: '0007000-00801000001'
<Status>
<Header
<InternalId>2</InternalId>
<Datatype>200</Datatype>
</Header>
<StatusInfo>
</StatusInfo>
</Status>
----- PL/SQL Error Stack -----
ORA-20104: ALR not found:'0007000-00801000001'
----- PL/SQL Call Stack -----
object line object
handle number name
00007FF9AF947390 1 anonymous block
result
ORA-01427: single-row subquery returns more than one row
Result I want:
<InternalId>2</InternalId>ORA-20104: ALR not found: '0007000-00801000001'
but for all rows
所有表中的行数太多
解决方案
您在评论中声明数据是 xml,但您提供的示例数据不是有效的 xml(“ The <number> 1 </number> is cat
”不是有效的 xml)。下面的解决方案使用正则表达式从<number>
无效 xml 中的标签中提取 id,并使用XMLTYPE().EXTRACT().GETSTRINGVAL()
函数从有效 xml 中提取 id。如果您的数据是 xml,请查看用于提取数据的 xml 本机函数,它们比 REGEXP 函数的性能要高得多。
WITH table_a (c) AS
(
SELECT 'The <number> 1 </number> is cat' FROM DUAL UNION ALL
SELECT 'The <number> 2 </number> is dog' FROM DUAL UNION ALL
SELECT 'The <number> 3 </number> is horse' FROM DUAL UNION ALL
SELECT 'The <number> 4 </number> is chicken' FROM DUAL UNION ALL
SELECT 'The <number> 5 </number> is hippo ' FROM DUAL
)
, table_b (c) AS
(
SELECT '<id>2</id>' FROM DUAL UNION ALL
SELECT '<id>4</id>' FROM DUAL UNION ALL
SELECT '<id>1</id>' FROM DUAL
)
SELECT
TRIM(REGEXP_REPLACE(a.c,'([^<>]+)(<number>)([^<>]+)(</number>)([^<>]+)','\5')) as result
FROM table_a a
JOIN table_b b ON TRIM(XMLTYPE(b.c).EXTRACT('/id/text()').GETSTRINGVAL()) = TRIM(REGEXP_REPLACE(a.c,'([^<>]+)(<number>)([^<>]+)(</number>)([^<>]+)','\3'));
RESULT
is cat
is dog
is chicken
推荐阅读
- reactjs - 反应回调未定义
- javascript - 如何在 React 中显示来自 vimeo 播放器的视频 iframe?
- laravel - 视图可以检查页面是否为 404?
- html - 当我添加一个复选框标签的类时,Css 停止工作
- wordpress - Wordpress 编辑器在编辑帖子时删除超链接
- bash - 用于比较 2 个文件并在需要的地方更新的 bash 脚本
- autohotkey - 单击没有 ID 的元素 - AutoHotKey
- c++ - 尝试通过 NAT 注册 pjsua2 时失败
- reactjs - 通过 ref 将视图添加到另一个
- java - 调用 onSharedPreferenceChanged 后应用主题未更改