sql-server - SQL Server XML 查询:查询具有相同名称的多个子元素
问题描述
在上一个问题中,我想知道如何JOIN
根据标识符对不同的 XML 元素使用 SQL。正如您在此处看到的,我得到了几个不错的解决方案。
现在我正在根据我的实际数据调整这个解决方案。不幸的是,我偶然发现了我在链接问题中提供的最小可行示例中不存在的新障碍。在我的实际数据中,我还有几个同名的子元素。请参阅以下示例数据中的元素<subElement>
。
<xml>
<dataSetData>
<text>ABC</text>
</dataSetData>
<generalData>
<id>123</id>
<text>text data</text>
<subElement>
<subData>sub example data AAA</subData>
</subElement>
<subElement>
<subData>sub example data BBB</subData>
</subElement>
</generalData>
<generalData>
<id>456</id>
<text>text data 2</text>
<subElement>
<subData>sub example data CCC</subData>
</subElement>
</generalData>
<specialData>
<id>123</id>
<text>special data text</text>
</specialData>
<specialData>
<id>456</id>
<text>special data text 2</text>
</specialData>
</xml>
预期结果应如下所示。
DataSetData | GeneralDataID | GeneralDataText | subData | SpecialDataTest
ABC | 123 | text data | sub example data AAA | special data text
ABC | 123 | text data | sub example data BBB | special data text
ABC | 456 | text data 2 | sub example data CCC | special data text 2
目前的解决方案(不考虑<subElement>
数据)如下(取自此处):
SELECT TheXml.value('(/xml/dataSetData/text/text())[1]', 'VARCHAR(20)') AS DataSetData
,B.*
, sp.value('(id/text())[1]', 'INT') AS SpecialDataID
, sp.value('(text/text())[1]', 'VARCHAR(30)') AS SpecialDataTest
INTO dbo.TestResult4
FROM dbo.TestXml
CROSS APPLY TheXml.nodes('/xml/generalData') AS A(g)
CROSS APPLY(SELECT g.value('(id/text())[1]', 'INT') AS GeneralDataID
, g.value('(text/text())[1]', 'VARCHAR(30)') AS GeneralDataText) B
OUTER APPLY TheXml.nodes('/xml/specialData[id=sql:column("B.GeneralDataID")]') AS special(sp);
解决方案
好吧,这很简单……
SELECT TheXml.value('(/xml/dataSetData/text/text())[1]', 'VARCHAR(20)') AS DataSetData
, B.*
, se.value('(subData/text())[1]','varchar(100)') AS SubData
, sp.value('(id/text())[1]', 'INT') AS SpecialDataID
, sp.value('(text/text())[1]', 'VARCHAR(30)') AS SpecialDataTest
FROM dbo.TestXml
CROSS APPLY TheXml.nodes('/xml/generalData') AS A(g)
CROSS APPLY(SELECT g.value('(id/text())[1]', 'INT') AS GeneralDataID
, g.value('(text/text())[1]', 'VARCHAR(30)') AS GeneralDataText) B
OUTER APPLY A.g.nodes('subElement') C(se)
OUTER APPLY TheXml.nodes('/xml/specialData[id=sql:column("B.GeneralDataID")]') AS D(sp);
推荐阅读
- spring-boot - 如何在百里香模板名称的地方发送html内容
- c - 是否可以使用 Huffman 编码压缩二进制文件?
- python - 如何返回 20 个列表数组中三个中适应度最高的个体?
- python - Python:找不到文件(pySerial)
- vb.net - 在 Visual Basic 中将项目从文本文件添加到多维数组
- scala - 按部分减少序列
- php - 使用变量 where-condition 从数据库创建 fusioncharts
- keras - 添加存在 advanced_activations 层的 dropout 层
- java - 不兼容的类型 - 在 timer.schedule run() curInterval 上找到:int required:boolean
- git - git 在 rebase 之后已经更新了远程分支后面的本地分支