此查询中有很多内容,因此我将分步进行解释。这是完整的查询:
with D as
(select xmltype('<Root>
<Status>SUCCESS</Status>
<Count>7</Count>
<Data>
<Content>S|123|03011990|5236158|19901254189684|</Content>
<Content>S|456|02011991|2584959|19916584159385|</Content>
</Data>
</Root>') dataStr from dual)
select *
from(
select id, trim(column_value) text,
rank() over(partition by id order by rownum) pos
from(
select rownum id, extract(column_value, 'Content/text()') text
from d,
table(xmlsequence(extract(dataStr,'Root/Data/*'))) x
),
xmltable(('"' || REPLACE(text, '|', '","') || '"'))
)pivot(
max(text) for pos in (1 as TYPE, 2 as VNO, 3 as F_DATE, 4 as F_NO, 5 as F_CNO)
)
我的 with 子句是使用 xmltype 命令将 xml 字符串转换为 xml 数据。
下一个是这个:
select rownum id, extract(column_value, 'Content/text()') text
from d,
table(xmlsequence(extract(dataStr,'Root/Data/*'))) x
这使用 xmlsequence 命令从 XML 中的对象中提取行。我正在使用 rownum 为每一行分配一个 ID。稍后我将需要该字段。
下一部分是我从这个网站上学到的一个绝妙技巧
select id, trim(column_value) text,
rank() over(partition by id order by rownum) pos
from(
select rownum id, extract(column_value, 'Content/text()') text
from d,
table(xmlsequence(extract(dataStr,'Root/Data/*'))) x
),
xmltable(('"' || REPLACE(text, '|', '","') || '"'))
它使用 XML 表命令和 REPLACE 函数使用分隔符“|”分割每个值。我在值周围使用了 trim 命令,以便将 XML 数据转换为字符串。我还使用排名窗口函数以便在下一步中进行旋转。
最后一部分是这样的:
select *
from(
select id, trim(column_value) text,
rank() over(partition by id order by rownum) pos
from(
select rownum id, extract(column_value, 'Content/text()') text
from d,
table(xmlsequence(extract(dataStr,'Root/Data/*'))) x
),
xmltable(('"' || REPLACE(text, '|', '","') || '"'))
)pivot(
max(text) for pos in (1 as TYPE, 2 as VNO, 3 as F_DATE, 4 as F_NO, 5 as F_CNO)
)
我以我在上一步中创建的“pos”等级列为轴,并为每个部分指定您指定的列名称。
我的最终结果如下所示:
ID TYPE VNO F_DATE F_NO F_CNO
1 S 123 03011990 5236158 19901254189684
2 S 456 02011991 2584959 19916584159385