【问题标题】:SQL XQuery and Cross Apply problems...too many rows in resultsSQL XQuery 和交叉应用问题...结果中的行太多
【发布时间】:2011-12-12 14:27:02
【问题描述】:

我有一张合同表。有几个列,最后一个 XML 列代表整个合同。合同内部是项目(1 个或更多),每个项目内部有 1 行或更多行。我需要能够选择所有行及其所在的项目,但我现在使用示例查询得到了奇怪的结果。

以下是 XML 示例:

<ZEstimateContract xmlns="http://schemas.datacontract.org/2004/07/Zeller.Gp" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Id="i1">
  <Name xmlns="http://schemas.datacontract.org/2004/07/Zynergy">QGPET0000000218</Name>
  <_projects>
    <ZEstimateProject z:Id="i9">
      <Name xmlns="http://schemas.datacontract.org/2004/07/Zynergy">&lt;BOM1&gt;</Name>
      <Parent i:nil="true" />
      <Quantity>1</Quantity>
      <_lines>
        <ZEstimateLine z:Id="i40">
          <Name xmlns="http://schemas.datacontract.org/2004/07/Zynergy">0.080 Aluminum 2ft x 4ft</Name>
          <_lines />
        </ZEstimateLine>
      </_lines>
      <_projects />
    </ZEstimateProject>
    <ZEstimateProject z:Id="i97">
      <Name xmlns="http://schemas.datacontract.org/2004/07/Zynergy">&lt;BOM2&gt;</Name>
      <Parent i:nil="true" />
      <Quantity>1</Quantity>      
      <_lines>
        <ZEstimateLine z:Id="i113">          
          <Name xmlns="http://schemas.datacontract.org/2004/07/Zynergy">#8X8SPOOL</Name>
        </ZEstimateLine>
      <_projects />
    </ZEstimateProject>
  </_projects>
</ZEstimateContract>

这是我的示例查询:

WITH XMLNAMESPACES('http://schemas.datacontract.org/2004/07/Zeller.Gp' AS ZC, 
    'http://schemas.datacontract.org/2004/07/Zynergy' AS ZYN)

SELECT Contract, LineName.value('.', 'varchar(50)') as LineItemName, ProjName.value('.', 'varchar(50)') as ProjectName
FROM dbo.tblContractMaster AS CM 
CROSS APPLY CM.FullContract.nodes('/ZC:ZEstimateContract/ZC:_projects/ZC:ZEstimateProject/ZYN:Name') as Proj(ProjName)
CROSS APPLY CM.FullContract.nodes('/ZC:ZEstimateContract/ZC:_projects/ZC:ZEstimateProject/ZC:_lines/ZC:ZEstimateLine/ZYN:Name') as Line(LineName)

结果是:

QGPET0000000218    0.080 Aluminum 2ft x 4ft          <BOM1>
QGPET0000000218    #8X8SPOOL                         <BOM1>
QGPET0000000218    0.080 Aluminum 2ft x 4ft          <BOM2>
QGPET0000000218    #8X8SPOOL                         <BOM2>

问题是“0.080 Aluminum 2ft x 4ft”仅在“BOM1”上,而“#8X8SPOOL”仅在“BOM2”上,因此结果中应该只有 2 行。请帮忙,谢谢!

【问题讨论】:

    标签: sql tsql xquery xquery-sql


    【解决方案1】:

    这应该有效。请注意,第二个 CROSS APPLY 链接到第一个(Proj.ProjName.nodes() 而不是 CM.FullContract.nodes()),而不是将您的 XML 重新分解为一个全新的表。这样做可以使您的子数据与正确的项目名称相关联:

    WITH XMLNAMESPACES('http://schemas.datacontract.org/2004/07/Zeller.Gp' AS ZC, 
        'http://schemas.datacontract.org/2004/07/Zynergy' AS ZYN)
    
    SELECT Contract, LineName.value('.', 'varchar(50)') as LineItemName, ProjName.value('.', 'varchar(50)') as ProjectName
    FROM @contract AS CM 
    CROSS APPLY CM.FullContract.nodes('/ZC:ZEstimateContract/ZC:_projects/ZC:ZEstimateProject/ZYN:Name') as Proj(ProjName)
    CROSS APPLY Proj.ProjName.nodes('../ZC:_lines/ZC:ZEstimateLine/ZYN:Name') as Line(LineName)
    

    【讨论】:

    • 太棒了!...按预期工作。也有道理...感谢您的帮助。
    • 嘿@mwigdahl,您是否也可以看看这个问题,因为您有点了解我已经拥有的数据结构。 stackoverflow.com/questions/8481388/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 2021-12-06
    • 2017-03-20
    相关资源
    最近更新 更多