简体   繁体   中英

SQLPLUS REGEXP_INSTR with more than a value

please i need your help. I have two tables A and B, for example

A

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 

'''

B

<id>2</id>
<id>4</id>
<id>1</id>

I want to cross check the values from B (numbers only) with all values from table A and have the result:

is dog
is chicken
is cat

I do this in "where" query's section like that(is just an example):

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;

My problem is with "FETCH NEXT 1 ROWS ONLY" returns only one row and without that i receive the sql error "ORA-01427: single-row subquery returns more than one row" (logic). How can i compare all numbers from B with all rows from A and receive the 3 results?

Thank you very much

You state in the comments that the data is xml, but the sample data you provided is not valid xml (" The <number> 1 </number> is cat " is not valid xml). The solution below uses regexp to extract the id from the <number> tag in the invalid xml and the XMLTYPE().EXTRACT().GETSTRINGVAL() function to extract the id from the valid xml. If your data is xml, look at the xml native functions to extract the data, they're a lot more performant than REGEXP functions.

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
 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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