sql - Snowflake 中 XML 横向扁平化的意外行为(已过滤 1 个值的行)

标签 sql xml snowflake-cloud-data-platform flatten

我正在 Snowflake 中处理一些 XML 数据,我试图访问 XML 子节点中的一些数据。

我想要的数据看起来像这样:

<Employee>
     <EmploymentStatuses>
        <EmployeeEmploymentStatus>
            <OtherInformation>
            </OtherInformation>            
        </EmployeeEmploymentStatus>
</Employee>

对于给定员工,他们可能有多个“EmployeeEmploymentStatus”。

为了解决这个问题,我创建了一个如下所示的 View :

SELECT
  XMLGET(XML_CONTENT,'EMPLOYEE_CODE'):"$"::STRING AS EMPLOYEE_CODE
  , XMLGET(EMPLOYMENT_STATUS.value, 'EffectiveStart'):"$"::DATE AS EffectiveStart
...........
FROM
  XML_FILE
  LATERAL FLATTEN(XML_CONTENT:"$") STATUSES
  LATERAL FLATTEN(STATUS.VALUE:"$") EMPLOYMENT_STATUS
WHERE 
 GET(STATUSES.VALUE, '@') = 'EmploymentStatuses'
AND GET(EMPSTAT.VALUE, '@') = 'EmployeeEmploymentStatus'

我遇到的问题是,虽然这在员工具有多个“就业状态”的情况下看起来很完美,但如果他们只有一个,则会将其过滤掉。 (即,具有 2 种或更多就业状态的任何人都会按照您的预期显示其所有状态,但只有 1 种就业状态的人根本不会出现)

如果我删除第二个横向展平并仅在选择部分中使用嵌套 XMLGET,我可以返回该值,但对于具有多个“EmploymentStatus”的员工,它仅返回第一个值。

当查看 STATUSES.VALUE 的输出时,它们在格式上看起来相同并且具有相同的标签。

我唯一能想到做的基本上就是这两个表的并集,或者做一些诸如将 'where 语句修改为类似这样的事情,然后需要在所有字段上合并语句:

GET(EMPLOYMENT_STATUS.value, '@') = 'EmployeeEmploymentStatus' OR GET(STATUSES.value:"$",'@')::STRING = 'EmployeeEmploymentStatus')

我测试了这个方法,它似乎有效,但它也似乎有点笨拙和不直观。

对此有任何建议,我们将不胜感激。

最佳答案

这是 XML 库中的常见错误(因此这不仅仅是雪花问题),并且 general accept solution就是获取您知道可以是数组的节点,并在进行分割之前将其转换为数组,以便它始终有效。

喜欢:

lateral flatten(to_array(xmlget(xmlget(src2.cdc_xml, 'portfolio'))))

IFF(IS_ARRAY(master_raw), master_raw, TO_ARRAY(master_raw)) as master

关于sql - Snowflake 中 XML 横向扁平化的意外行为(已过滤 1 个值的行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70851959/

相关文章:

java - mybatis 列名冲突?

xml - 用于具有任意标签的 XML 文档的 XSLT

c# - 通过 Soap 传递数字数组

python - 如何捕获 Snowflake 中 Python UDF 上的 STDOUT 以作为字符串返回?

amazon-s3 - 如何基于S3分区数据在雪花中创建外部表

sql - PostgreSQL 按子查询排序

c# - 单元测试数据库修改函数?

sql - 如何使用季度末日期进行数学计算?

xml - 如何获取所有使用的命名空间的列表?

snowflake-cloud-data-platform - 如何删除雪花数据库表中的重复记录