我有以下 XML 文件,我已将其作为 VARIANT 类型导入到 Snowflake 表中。
<xyz>
<Header>
<VersionInfo>
<Version>2.1.0</Version>
<Notes>Draft report v1</Notes>
</VersionInfo>
<Environment>Env1</Environment>
<SubID>5787685</SubID>
</Header>
<Items>
<NEWT>
<ItemNo>12345</ItemNo>
<ItemBody>
<RptDt>2021-01-19T06:54:42.483Z</RptDt>
<RptEnt>
<Entity>123</Entity>
</RptEnt>
<IsVerified>FALSE</IsVerified>
</ItemBody>
</NEWT>
</Items>
<Items>
<NEWT>
<ItemNo>23456</ItemNo>
<ItemBody>
<RptDt>2021-01-19T06:54:42.483Z</RptDt>
<RptEnt>
<Entity>2346</Entity>
</RptEnt>
<IsVerified>TRUE</IsVerified>
</ItemBody>
</NEWT>
</Items>
</xyz>
我正在尝试解析 XML 并从数据中生成两个不同的雪花表。第一个查询有效,并从该部分提取数据。 这是查询:
-- get header and version
SELECT
XMLGET(Header.value, 'Environment'):"$"::string Environment,
XMLGET(Header.value, 'SubID'):"$"::string SubID,
XMLGET(Version.value, 'Version'):"$"::string Version,
XMLGET(Version.value, 'Notes'):"$"::string Notes
FROM
MyTable ,
LATERAL FLATTEN(GET(xml_import, '$')) Header ,
LATERAL FLATTEN(GET(Header.value, '$')) Version
WHERE
GET(Header.value, '@') = 'Header'
and GET(Version.value, '@') = 'VersionInfo';
下面是想要的结果:
ENVIRONMENT SUBID VERSION NOTES
Env1 5787685 2.1.0 Draft report v1
对于下一部分,我在解析该部分的所有级别时遇到问题。所需的结果将是一个表格,其中每个表格都有一行数据,来自 XML 文件。
ItemNo RptDt RptEnt IsVerified
12345 2021-01-19T06:54:42.483Z 123 FALSE
23456 2021-01-19T06:54:42.483Z 2346 TRUE
我尝试编写以下 SQL,但我很难过滤行和导航嵌套级别。
-- get items and reports
select
XMLGET(flt1.value, 'RptDt'):"$"::string RptDate,
XMLGET(flt1.value, 'IsVerified'):"$"::string IsVerified
FROM
MyTable src1,
lateral flatten(to_array(xmlget(xmlget(src1.xml_import, 'Items'), 'NEWT'):"$")) flt1
我确信有一种更有效的方法来查询这些数据并将其转换为表格格式。任何人都可以建议如何遍历多个级别和多个重复,而忽略
答案 0 :(得分:1)
我正在寻找缩短此代码的方法 - 但它适用于您的示例:
select xmlget(emp.value:"$", 'ItemNo'):"$" ItemNo
, xmlget(xmlget(emp.value:"$", 'ItemBody'), 'RptDt'):"$"::timestamp RptDt
, xmlget(xmlget(emp.value:"$", 'ItemBody'), 'RptEnt'):"$":"$" RptEnt
, xmlget(xmlget(emp.value:"$", 'ItemBody'), 'IsVerified'):"$"::boolean IsVerified
from onexml
, lateral flatten(onexml.xml_import:"$") emp
where get(emp.value, '@')='Items';
示例数据:
create temp table onexml as
select parse_xml('<xyz>
<Header>
<VersionInfo>
<Version>2.1.0</Version>
<Notes>Draft report v1</Notes>
</VersionInfo>
<Environment>Env1</Environment>
<SubID>5787685</SubID>
</Header>
<Items>
<NEWT>
<ItemNo>12345</ItemNo>
<ItemBody>
<RptDt>2021-01-19T06:54:42.483Z</RptDt>
<RptEnt>
<Entity>123</Entity>
</RptEnt>
<IsVerified>FALSE</IsVerified>
</ItemBody>
</NEWT>
</Items>
<Items>
<NEWT>
<ItemNo>23456</ItemNo>
<ItemBody>
<RptDt>2021-01-19T06:54:42.483Z</RptDt>
<RptEnt>
<Entity>2346</Entity>
</RptEnt>
<IsVerified>TRUE</IsVerified>
</ItemBody>
</NEWT>
</Items>
</xyz>') xml_import;