You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL Server中使用T-SQL从指定XML数据生成目标表格

T-SQL实现XML转结构化表格方案

适用SQL Server 2017及以上版本(支持STRING_AGG函数)

直接使用STRING_AGG拼接同一客户的多条请求,写法更简洁:

Declare @Result XML
SET @Result='
<General>
  <Customer>
    <model_year>2011</model_year>
    <vehicle_id>1</vehicle_id>
    <customer_requests>
      <request>
        <definition>I want to new car tyre</definition>
      </request>
      <request>
        <definition>I want to new headlight</definition>
      </request>
    </customer_requests>
    <mileage>34000</mileage>
  </Customer>
  <Customer>
    <model_year>2012</model_year>
    <vehicle_id>2</vehicle_id>
    <customer_requests>
      <request>
        <definition>I want to general maintenance</definition>
      </request>
    </customer_requests>
    <mileage>35000</mileage>
  </Customer>
</General>
'

SELECT
    T.Customer.value('(model_year/text())[1]', 'INT') AS model_year,
    T.Customer.value('(vehicle_id/text())[1]', 'INT') AS vehicle_id,
    STRING_AGG(R.Request.value('(definition/text())[1]', 'NVARCHAR(200)'), ',') AS request,
    T.Customer.value('(mileage/text())[1]', 'INT') AS mileage
FROM @Result.nodes('/General/Customer') AS T(Customer)
CROSS APPLY T.Customer.nodes('customer_requests/request') AS R(Request)
GROUP BY
    T.Customer.value('(model_year/text())[1]', 'INT'),
    T.Customer.value('(vehicle_id/text())[1]', 'INT'),
    T.Customer.value('(mileage/text())[1]', 'INT')

适用SQL Server 2016及更早版本(无STRING_AGG函数)

使用STUFF + FOR XML PATH实现字符串拼接,兼容性更强:

Declare @Result XML
SET @Result='
<General>
  <Customer>
    <model_year>2011</model_year>
    <vehicle_id>1</vehicle_id>
    <customer_requests>
      <request>
        <definition>I want to new car tyre</definition>
      </request>
      <request>
        <definition>I want to new headlight</definition>
      </request>
    </customer_requests>
    <mileage>34000</mileage>
  </Customer>
  <Customer>
    <model_year>2012</model_year>
    <vehicle_id>2</vehicle_id>
    <customer_requests>
      <request>
        <definition>I want to general maintenance</definition>
      </request>
    </customer_requests>
    <mileage>35000</mileage>
  </Customer>
</General>
'

SELECT
    T.Customer.value('(model_year/text())[1]', 'INT') AS model_year,
    T.Customer.value('(vehicle_id/text())[1]', 'INT') AS vehicle_id,
    STUFF((
        SELECT ',' + R.Request.value('(definition/text())[1]', 'NVARCHAR(200)')
        FROM T.Customer.nodes('customer_requests/request') AS R(Request)
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS request,
    T.Customer.value('(mileage/text())[1]', 'INT') AS mileage
FROM @Result.nodes('/General/Customer') AS T(Customer)

逻辑说明

  • nodes()方法用于将XML节点集合拆分为行集,分别提取所有<Customer>节点、以及每个客户下的所有<request>节点
  • value()方法用于从XML节点中提取指定路径的文本值,转换为对应SQL数据类型
  • 两种写法最终输出结果完全匹配要求的表格格式

内容的提问来源于stack exchange,提问作者Kara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 15:36:03