Snowflake XML 解析:提取 snowflake sql 中标签值的属性
Snowflake XML parsing: extract attribute of a tag value in snowflake sql
<ROOM name="Closet">
<ITEMS>
<ITEM ageM="6" brand="Ross'" costToReplace="25" desc="Sweater shawl" id="11" lineNum="11" method="2" purchasedFrom="Ross'" qtyLost="1" use="1">
<IMAGES></IMAGES>
<ITEM_RECEIPT_INFOS></ITEM_RECEIPT_INFOS>
</ITEM>
<ITEM ageY="2" brand="GAP" costToReplace="20" desc="white long sleeve shirt" id="12" lineNum="12" method="2" purchasedFrom="GAP" qtyLost="1">
<IMAGES></IMAGES>
<ITEM_RECEIPT_INFOS></ITEM_RECEIPT_INFOS>
</ITEM>
</ITEMS>
</ROOM>
<ROOM name="Kitchen">
<ITEMS>
<ITEM ageM="6" ageY="1" brand="Pier 1 Imports" costToReplace="30" desc="Wine decanter" id="13" lineNum="13" method="3" purchasedFrom="Pier 1 Imports" qtyLost="1" use="1">
<IMAGES></IMAGES>
<ITEM_RECEIPT_INFOS></ITEM_RECEIPT_INFOS>
</ITEM>
</ITEMS>
</ROOM>
</ROOMS>
ID return 值假设为 11、12、13,但我只得到 11、12。
我的代码:
栏名是房间,
Table 名字是 item_xml
select
rs.value:"@id" ::string
from item_xml, LATERAL FLATTEN( INPUT => XMLGET(XMLGET(item_xml.room, 'ROOM'),'ITEMS'):"$") rs;
有人可以帮助我吗?非常感谢!
问题是您要遍历两个数组,但只有一个 FLATTEN,
因此你需要另一个 FLATEN,但这里的诀窍是“厨房”在 ITEMS 中只有一个项目,大多数 XML 解析不正确地映射到一个对象(也就是这种情况也发生在雪花中)。
因此,在使用之前,您必须将“items”的输出从“Room”转换为数组:
select
i.value:"@id" ::string
from item_xml
,LATERAL FLATTEN( INPUT => room:"$") as r
,LATERAL FLATTEN( INPUT => to_array(XMLGET(r.value,'ITEMS'):"$") ) i
;
给出:
I.VALUE:"@ID" ::STRING
11
12
13
技术上你真的应该包装所有数组,所以当数据是单个项目时,你 SQL 不会爆炸。因此你的解决方案应该是:
select
i.value:"@id" ::string
from item_xml
,LATERAL FLATTEN( INPUT => to_array(room:"$")) as r
,LATERAL FLATTEN( INPUT => to_array(XMLGET(r.value,'ITEMS'):"$") ) i
;
<ROOM name="Closet">
<ITEMS>
<ITEM ageM="6" brand="Ross'" costToReplace="25" desc="Sweater shawl" id="11" lineNum="11" method="2" purchasedFrom="Ross'" qtyLost="1" use="1">
<IMAGES></IMAGES>
<ITEM_RECEIPT_INFOS></ITEM_RECEIPT_INFOS>
</ITEM>
<ITEM ageY="2" brand="GAP" costToReplace="20" desc="white long sleeve shirt" id="12" lineNum="12" method="2" purchasedFrom="GAP" qtyLost="1">
<IMAGES></IMAGES>
<ITEM_RECEIPT_INFOS></ITEM_RECEIPT_INFOS>
</ITEM>
</ITEMS>
</ROOM>
<ROOM name="Kitchen">
<ITEMS>
<ITEM ageM="6" ageY="1" brand="Pier 1 Imports" costToReplace="30" desc="Wine decanter" id="13" lineNum="13" method="3" purchasedFrom="Pier 1 Imports" qtyLost="1" use="1">
<IMAGES></IMAGES>
<ITEM_RECEIPT_INFOS></ITEM_RECEIPT_INFOS>
</ITEM>
</ITEMS>
</ROOM>
</ROOMS>
ID return 值假设为 11、12、13,但我只得到 11、12。
我的代码:
栏名是房间, Table 名字是 item_xml
select
rs.value:"@id" ::string
from item_xml, LATERAL FLATTEN( INPUT => XMLGET(XMLGET(item_xml.room, 'ROOM'),'ITEMS'):"$") rs;
有人可以帮助我吗?非常感谢!
问题是您要遍历两个数组,但只有一个 FLATTEN,
因此你需要另一个 FLATEN,但这里的诀窍是“厨房”在 ITEMS 中只有一个项目,大多数 XML 解析不正确地映射到一个对象(也就是这种情况也发生在雪花中)。
因此,在使用之前,您必须将“items”的输出从“Room”转换为数组:
select
i.value:"@id" ::string
from item_xml
,LATERAL FLATTEN( INPUT => room:"$") as r
,LATERAL FLATTEN( INPUT => to_array(XMLGET(r.value,'ITEMS'):"$") ) i
;
给出:
I.VALUE:"@ID" ::STRING |
---|
11 |
12 |
13 |
技术上你真的应该包装所有数组,所以当数据是单个项目时,你 SQL 不会爆炸。因此你的解决方案应该是:
select
i.value:"@id" ::string
from item_xml
,LATERAL FLATTEN( INPUT => to_array(room:"$")) as r
,LATERAL FLATTEN( INPUT => to_array(XMLGET(r.value,'ITEMS'):"$") ) i
;