希望有人能帮助我进行SQL查询,我正在try 合并两个XML列,我目前使用的是SQL Azure 2019.

第一个XML

<HOME>
    <VALIDITYLIST>
        <VALIDITY STATE="1">
            <VALIDITYTYPE>1</VALIDITYTYPE>
            <GROUPCODE>DEFAULT</GROUPCODE>
            <ENTRY/>
            <CARD>2</CAR>
            <GIFTAID/>
            <VARIABLERANGE>false</VARIABLERANGE>
            <DAYS>365</DAYS>
            <NOTOPERATING>false</NOTOPERATING>
            <VALIDITYLIST/>
            <YPERESTRICTIONLIST/>
            <METRALOCKERV2>
                <LOCKERITEMID/>
            </METRALOCKERV2>
            <REQUIREDVAREXPDATE/>
        </VALIDITY>
    </VALIDITYLIST>
</HOME>

第二个XML

<HOME>
    <VALIDITYLIST>
        <VALIDITY STATE="1">
            <VALIDITYTYPE>1</VALIDITYTYPE>
            <GROUPCODE>DEFAULT</GROUPCODE>
            <GIFTAID/>
            <DYNAMICP/>
            <VALIDITYLIST>
                <VALIDITY STATE="1">
                    <VALIDITYTYPE>2</VALIDITYTYPE>
                    <EVENT>3</EVENT>
                    <ENTRYTYPE>2</ENTRYTYPE>
                    <NUMENTRY>1</NUMENTRY>
                </VALIDITY>
            </VALIDITYLIST>
        </VALIDITY>
    </VALIDITYLIST>
</HOME>

SQL以某种方式合并了两个XML,并且只返回值所在的 node .就像这样.

<HOME>
    <VALIDITYLIST>
        <VALIDITY>
            <VALIDITYTYPE>1</VALIDITYTYPE>
            <GROUPCODE>DEFAULT</GROUPCODE>
            <CARD>2</CAR>
            <VARIABLERANGE>false</VARIABLERANGE>
            <DAYS>365</DAYS>
            <NOTOPERATING>false</NOTOPERATING>
            <VALIDITYLIST>
                <VALIDITY>
                    <VALIDITYTYPE>2</VALIDITYTYPE>
                    <EVENT>3</EVENT>
                    <ENTRYTYPE>2</ENTRYTYPE>
                    <NUMENTRY>1</NUMENTRY>
                </VALIDITY>
            </VALIDITYLIST>
        </VALIDITY>
    </VALIDITYLIST>
</HOME> 

感谢大家分享你的 idea [编辑部分如下]

我仍然希望在SQL中处理.由于 node 是固定的,我正在考虑通过读取单独的XML创建两个表,然后根据值构造新的XML,现在我停留在第一部分,即读取XML. 这就是我想要的,当我读取第二个XML但返回空值时,我应该会看到值1和2,你能看到我做错了什么吗?

select @XML2.value('(/HOME/VALIDITYTYPE/node())[1]', 'nvarchar(max)') as VALIDITYTYPE
, @XML2.value('(/HOME/VALIDITYLIST/VALIDITYLIST/VALIDITYTYPE/node())[1]', 'nvarchar(max)') as VALIDITYTYPE

推荐答案

是的,这在纯SQL中是可能的,使用XQuery和完全连接两个XML,然后使用FOR XML重新构造它

SELECT *,
  NewXml = (
    SELECT
      VALIDITYLIST = (
        SELECT
          ISNULL(x1.query('.'), x2.query('.'))
        FROM
          t.Xml1.nodes('HOME/VALIDITYLIST/VALIDITY/*[.//text()]') x1(x1)
        FULL JOIN
          t.Xml2.nodes('HOME/VALIDITYLIST/VALIDITY/*[.//text()]') x2(x2)
          ON x2.x2.value('local-name(.)','nvarchar(30)') = x1.x1.value('local-name(.)','nvarchar(30)')
        FOR XML PATH(''), ROOT('VALIDITY'), TYPE
      )
    FOR XML PATH(''), ROOT('HOME'), TYPE
  )
FROM YourTable t;

谓词*[.//text()]判断当前 node 是否在任何深度具有任何后代文本元素.

我们将当前 node 的名称联接local-name(.),如果第一列的结果可用,则获取第一列的结果,否则获取第二列的结果.如果列未命名,则FOR XML不添加 node 名.

所有这些都假设您始终只有一个HOME/VALIDITYLIST/VALIDITY node ,否则情况会更复杂.

db<>fiddle

Sql相关问答推荐

PostgreSQL:获取每家店铺收入最高的员工

从以前的非空值行中获取值

Lag()函数的差异:R与SQL(将R代码转换为SQL)

在SQL中使用类别值将行转置为列

从日期开始向前填充重复项

收到%1、%2或%2邮箱的唯一客户

查询每周数据(周一至周日),避免年度日期重叠

如果多行科目有一行在指定的日期范围内,如何 Select 该科目在该日期之前的所有行?

在Athena中使用regexp提取括号前的字符串值

显示十进制列,但尽可能显示为整数

如何使用jsonn_populate_record()插入到包含IDENTITY列的表中

在特定条件下使用 LAG,确定要采用什么 LAG 值?

列(值不为空)到其他有序列

如何在 SQL 中将两行(或多行)jsonb 数组合并为一行

在Snowflake中如何使用SQL对版本字符串进行排序?

每组使用平均值来填补缺失值的SQL

SQL Server 分区和 Run Case 语句

如何计算每行出现的次数并显示在另一个表中?

运算符不存在:integer = bigint[]

如何跨行合并以删除 SQL 中的空值?