问题描述
<?xml version="1.0" encoding="UTF-8"?>
<root>
<pats>
<pat>
<id>1</id>
<pat_maps>
<pat_map>
<pgid>100</pgid>
<pgname>test</pgname>
</pat_map>
<pat_map>
<pgid>101</pgid>
<pgname>test1</pgname>
</pat_map>
</pat_maps>
</pat>
<pat>
<id>2</id>
<pat_maps>
<pat_map>
<pgid>102</pgid>
<pgname>test2</pgname>
</pat_map>
</pat_maps>
</pat>
<pat>
<id>3</id>
<pat_maps>
<pat_map>
<pgid>104</pgid>
<pgname>test6</pgname>
</pat_map>
<pat_map>
<pgid>105</pgid>
<pgname>test7</pgname>
</pat_map>
</pat_maps>
</pat>
</pats>
</root>
我想通过以下方式插入数据
ID pgid pgname
1 100 test
1 101 test1
2 102 test2
3 104 test6
3 105 test7
在下面尝试过,但是正在应用交叉联接
with x(t) as (select '<?xml version="1.0" encoding="UTF-8"?>
<root>
<pats>
..............
..........
</pat>
</pats>
</root>'::xml AS t
),base_id as (SELECT
unnest(xpath('/root/pats/pat/id/text()',t)) AS id
from x
),nested_rec as ( select
unnest(xpath('pgid/text()',cat_assn_list)) AS pgid,unnest(xpath('pgname/text()',cat_assn_list)) AS pgname
from (select unnest(xpath('/root/pats/pat/pat_maps/pat_map',t)) cat_assn_list from x) q
)
select base_id.*,nested_rec.* from base_id,nested_rec;
******* output *********
ID PGID PGNAME
"1" "100" "test"
"1" "101" "test1"
"1" "102" "test2"
"1" "104" "test6"
"1" "105" "test7"
"2" "100" "test"
"2" "101" "test1"
"2" "102" "test2"
"2" "104" "test6"
"2" "105" "test7"
"3" "100" "test"
"3" "101" "test1"
"3" "102" "test2"
"3" "104" "test6"
"3" "105" "test7"
我还没有找到一种方法,如何明智地嵌套XML ID并准备结果集? 还有没有其他方法可以在不使用Postgresql中的XPath函数的情况下将xml数据转换为表? 预先感谢。
解决方法
以下内容可以满足您的要求,并且简短一些:
select (xpath('/pat/id/text()',d.pat))[1]::text::int as id,(xpath('/pat_map/pgid/text()',m.map))[1]::text::int as pgid,(xpath('/pat_map/pgname/text()',m.map))[1]::text as pgname
from x
cross join unnest(xpath('/root/pats/pat',x.t)) as d(pat)
cross join unnest(xpath('/pat/pat_maps/pat_map',d.pat)) as m(map)
;
使用更现代的Postgres版本,您可以使用xmltable()
:
select d.*
from x
cross join xmltable ('/root/pats/pat/pat_maps/pat_map'
passing t
columns
id integer path '../../id',pgid integer path 'pgid',pgname text path 'pgname') as d