我将以下XML数据放在一列中:
<Employee_part part_id="A" part_name="ABC" >
<Employee_scoring_information >
<keyset keyset_weight="1" number_of_keyset_members="1">
<integer_key value="2"/>
</keyset>
</Employee_scoring_information>
</Employee_part>
<Employee_part part_id="B" part_name="BCD" >
<Employee_scoring_information >
<match_keyset keyset_weight="1" number_of_keyset_members="3">
<integer_key value="2"/>
<source_key correct_target_id="4" source_key_id="1"/>
<source_key correct_target_id="1" source_key_id="2"/>
<source_key correct_target_id="2" source_key_id="3"/>
</match_keyset>
<match_keyset keyset_weight="1" number_of_keyset_members="3">
<source_key correct_target_id="5" source_key_id="1"/>
<source_key correct_target_id="1" source_key_id="2"/>
<source_key correct_target_id="2" source_key_id="3"/>
</match_keyset>
</Employee_scoring_information>
</Employee_part>
<Employee_part part_id="C" part_name="CDE" >
<Employee_scoring_information >
<keyset keyset_weight="1" number_of_keyset_members="2">
<integer_key value="1"/>
<integer_key value="2"/>
</keyset>
</Employee_scoring_information>
</Employee_part>
XML有三个部分(Employee_part part_id =&#34; A&#34;,&#34; B&#34;,&#34; C&#34;)A部分有键集,B部分有 match_keyset ,部分c有键集。当它有键集时,我需要从integer_key / @ Value(Ex:2)中提取数据,当它有match_keyset时,我需要从source_key correct_target_id,source_key_id中提取数据,格式为(例如:1 / 4,2 / 1, 3/2; 1 / 5,2 / 1,3 / 2;)。每个部分都由Pipe(|)符号分隔。
我正在尝试编写以下查询以显示以下输出: 2 | 1 / 4,2 / 1,3 / 2; 1 / 5,2 / 1,3 / 2; | 1,2
SELECT CASE EXISTSNODE (EMP_CNTNT_XML,
'/Employee/Employee_content/Employee_part')
WHEN 1
THEN
RTRIM (
REPLACE (
REPLACE (
CAST (
XMLQUERY (
'
for $i in //Employee_part/@part_id return
concat
(
concat
(
xs:string
(
for $x in //Employee_part where $x/@part_id = $i return
for $y in $x//integer_key/@value return
concat
(
xs:string($y)
,","
)
)
,
xs:string
(
for $k in //Employee_part where $k/@part_id = $i return
concat(
xs:string(
for $x in $k/@source_key_id return
for $y in $k/@correct_target_id return
concat(xs:string($x), "/", xs:string($y), "" ) )
,",")
)
)
,
"|"
)
'
PASSING EMP_CNTNT_XML RETURNING CONTENT) AS VARCHAR2 (1000)),
' ',
''),
',|',
'|'),
'|')
END
AS XML_DATA
FROM Employee
WHERE emp_no = 'SCH1234';
答案 0 :(得分:0)
我的建议是将XML更改为关系数据,如下所示:
CREATE TABLE emp AS
SELECT XMLTYPE('<Employee><Employee_content>
<Employee_part part_id="A" part_name="ABC" >
<Employee_scoring_information >
<keyset keyset_weight="1" number_of_keyset_members="1">
<integer_key value="2"/>
</keyset>
</Employee_scoring_information>
</Employee_part>
<Employee_part part_id="B" part_name="BCD" >
<Employee_scoring_information >
<match_keyset keyset_weight="1" number_of_keyset_members="3">
<integer_key value="2"/>
<source_key correct_target_id="4" source_key_id="1"/>
<source_key correct_target_id="1" source_key_id="2"/>
<source_key correct_target_id="2" source_key_id="3"/>
</match_keyset>
<match_keyset keyset_weight="1" number_of_keyset_members="3">
<source_key correct_target_id="5" source_key_id="1"/>
<source_key correct_target_id="1" source_key_id="2"/>
<source_key correct_target_id="2" source_key_id="3"/>
</match_keyset>
</Employee_scoring_information>
</Employee_part>
<Employee_part part_id="C" part_name="CDE" >
<Employee_scoring_information >
<keyset keyset_weight="1" number_of_keyset_members="2">
<integer_key value="1"/>
<integer_key value="2"/>
</keyset>
</Employee_scoring_information>
</Employee_part>
</Employee_content></Employee>') AS Employee_part
FROM dual;
CREATE OR REPLACE VIEW EMP_SCORING_INFORMATION AS
SELECT part_id, part_name, SCORING_INFORMATION
FROM EMP e
CROSS JOIN XMLTABLE('/Employee/Employee_content/Employee_part' PASSING EMPLOYEE_PART COLUMNS
part_id VARCHAR2(10) PATH '@part_id',
part_name VARCHAR2(10) PATH '@part_name',
SCORING_INFORMATION XMLTYPE PATH 'Employee_scoring_information'
) p;
CREATE OR REPLACE VIEW EMP_MATCH_KEYSET AS
SELECT part_id, part_name, keyset_weight, number_of_keyset_members, keyset_NO, keyset
FROM EMP_SCORING_INFORMATION e
CROSS JOIN XMLTABLE('/Employee_scoring_information/match_keyset' PASSING SCORING_INFORMATION COLUMNS
keyset_weight INTEGER PATH '@keyset_weight',
number_of_keyset_members INTEGER PATH '@number_of_keyset_members',
keyset_NO FOR ORDINALITY,
keyset XMLTYPE PATH '/'
) p;
CREATE OR REPLACE VIEW EMP_KEYSET AS
SELECT part_id, part_name, keyset_weight, number_of_keyset_members, keyset_NO, keyset
FROM EMP_SCORING_INFORMATION e
CROSS JOIN XMLTABLE('/Employee_scoring_information/keyset' PASSING SCORING_INFORMATION COLUMNS
keyset_weight INTEGER PATH '@keyset_weight',
number_of_keyset_members INTEGER PATH '@number_of_keyset_members',
keyset_NO FOR ORDINALITY,
keyset XMLTYPE PATH '/'
) p;
CREATE OR REPLACE VIEW EMP_MATCH_KEYSET_source_key AS
SELECT keyset_NO, part_id, part_name, keyset_weight, number_of_keyset_members,
key_NO, correct_target_id, source_key_id
FROM EMP_MATCH_KEYSET e
CROSS JOIN XMLTABLE('/match_keyset/source_key' PASSING keyset COLUMNS
correct_target_id INTEGER PATH '@correct_target_id',
source_key_id INTEGER PATH '@source_key_id',
key_NO FOR ORDINALITY
)p;
CREATE OR REPLACE VIEW EMP_MATCH_KEYSET_INTEGER_KEY AS
SELECT keyset_NO, part_id, part_name, keyset_weight, number_of_keyset_members,
key_NO, integer_key
FROM EMP_MATCH_KEYSET e
CROSS JOIN XMLTABLE('/match_keyset/integer_key' PASSING keyset COLUMNS
integer_key INTEGER PATH '@value',
key_NO FOR ORDINALITY
)p;
CREATE OR REPLACE VIEW EMP_KEYSET_INTEGER_KEY AS
SELECT keyset_NO, part_id, part_name, keyset_weight, number_of_keyset_members,
key_NO, integer_key
FROM EMP_KEYSET e
CROSS JOIN XMLTABLE('/keyset/integer_key' PASSING keyset COLUMNS
integer_key INTEGER PATH '@value',
key_NO FOR ORDINALITY
)p;
我不完全了解您的要求,但作为起点,您可以使用此查询:
WITH t AS
(SELECT LISTAGG(SOURCE_KEY_ID||'/'||CORRECT_TARGET_ID, ',') WITHIN GROUP (ORDER BY key_NO) AS KEY_ID, keyset_NO
FROM EMP_MATCH_KEYSET_SOURCE_KEY
GROUP BY keyset_NO)
SELECT LISTAGG(KEY_ID, '; ') WITHIN GROUP (ORDER BY keyset_NO)
FROM t;
1/4,2/1,3/2; 1/5,2/1,3/2
使用相当简单的JOIN,UNION和/或CASE,您应该能够获得所需的输出。