无法对XML中的多个列进行分组

时间:2016-10-06 10:27:02

标签: sql xml grouping nodes

我有一个查询返回在SQL中的varchar(max)xml字段中保存的服务器详细信息 我的问题是驱动器列,服务器可以有多个驱动器,但这些是XML中服务器父节点下的多个子项,我使用CASE WHEN行将驱动器分成列,但每个驱动器号生成自己的行,所以带有2个驱动器的服务器会创建2行

STName          STDescription           RTName          RTDescription               RTQty    RTCode NTName          NTDescription               NTPVLAN NTSVLAN NTDomain    NTRam   NTCpus  NTVMTemplate    NTSCOM  RTCode  Cdrive  Ddrive  Edrive  Fdrive  Gdrive
Basic Service   Single Server Service   Standard Server Basic server configuration  1        STD    Standard Server Basic server configuration  {{int}} NULL    {{primary}} 4       2       1NIC2012R2CLUST TRUE    STD     50      NULL    NULL    NULL    NULL
Basic Service   Single Server Service   Standard Server Basic server configuration  1        STD    Standard Server Basic server configuration  {{int}} NULL    {{primary}} 4       2       1NIC2012R2CLUST TRUE    STD     NULL    20      NULL    NULL    NULL

我希望调整我的代码以将两个驱动器放在同一行上是一项相当简单的工作吗?

STName          STDescription           RTName          RTDescription               RTQty    RTCode NTName          NTDescription               NTPVLAN NTSVLAN NTDomain    NTRam   NTCpus  NTVMTemplate    NTSCOM  RTCode  Cdrive  Ddrive  Edrive  Fdrive  Gdrive
Basic Service   Single Server Service   Standard Server Basic server configuration  1        STD    Standard Server Basic server configuration  {{int}} NULL    {{primary}} 4       2       1NIC2012R2CLUST TRUE    STD     50      20      NULL    NULL    NULL

这是我的查询

DECLARE @XML xml; SET @XML = (SELECT CONVERT(XML, CONVERT(NVARCHAR(max), TemplateXml )) FROM dbTemplates FOR XML AUTO, Root('ACME'))
SELECT
ST.C.value('(Name/text())[1]', 'nvarchar(max)') as STName,
ST.C.value('(Description/text())[1]', 'nvarchar(max)') as STDescription,
RT.C.value('(Name/text())[1]', 'nvarchar(max)') as RTName,
RT.C.value('(Description/text())[1]', 'nvarchar(max)') as RTDescription,
RT.C.value('(Quantity/text())[1]', 'nvarchar(max)') as RTQty,
RT.C.value('(Code/text())[1]', 'nvarchar(max)') as RTCode,
NT.C.value('(Name/text())[1]', 'nvarchar(max)') as NTName,
NT.C.value('(Description/text())[1]', 'nvarchar(max)') as NTDescription,
NT.C.value('(PrimaryVlan/text())[1]', 'nvarchar(max)') as NTPVLAN,
NT.C.value('(SecondaryVlan/text())[1]', 'nvarchar(max)') as NTSVLAN,
NT.C.value('(Domain/text())[1]', 'nvarchar(max)') as NTDomain,
NT.C.value('(RamSize/text())[1]', 'nvarchar(max)') as NTRam,
NT.C.value('(CpuCores/text())[1]', 'nvarchar(max)') as NTCpus,
NT.C.value('(VmTemplate/text())[1]', 'nvarchar(max)') as NTVMTemplate,
NT.C.value('(ScomInstall/text())[1]', 'nvarchar(max)') as NTSCOM,
NT.C.value('(SccmInstall/text())[1]', 'nvarchar(max)') as NTSCCM,
CASE WHEN DP.C.value('(Letter/text())[1]', 'nvarchar(max)') = 'C' THEN DP.C.value('(Capacity/text())[1]', 'nvarchar(max)') END AS Cdrive,
CASE WHEN DP.C.value('(Letter/text())[1]', 'nvarchar(max)') = 'D' THEN DP.C.value('(Capacity/text())[1]', 'nvarchar(max)') END AS Ddrive,
CASE WHEN DP.C.value('(Letter/text())[1]', 'nvarchar(max)') = 'E' THEN DP.C.value('(Capacity/text())[1]', 'nvarchar(max)') END AS Edrive,
CASE WHEN DP.C.value('(Letter/text())[1]', 'nvarchar(max)') = 'F' THEN DP.C.value('(Capacity/text())[1]', 'nvarchar(max)') END AS Fdrive,
CASE WHEN DP.C.value('(Letter/text())[1]', 'nvarchar(max)') = 'G' THEN DP.C.value('(Capacity/text())[1]', 'nvarchar(max)') END AS Gdrive
from @XML.nodes('ACME/dbTemplates/ServiceTemplate') as ST(C)
outer apply ST.C.nodes('Roles') as RO(C)
outer apply RO.C.nodes('RoleTemplate') as RT(C)
outer apply RT.C.nodes('NodeTemplate') as NT(C)
outer apply NT.C.nodes('Drives') as DR(C)
outer apply DR.C.nodes('DriveParameter') as DP(C)
ORDER BY STName,RTName

以下是XML的一部分

<ACME>
  <dbTemplates>
    <ServiceTemplate xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <TemplateId>3205ac97-6396-4acb-8f93-5704297f1bbc</TemplateId>
      <Name>Basic Service</Name>
      <Description>Single Server Service</Description>
      <Roles>
        <RoleTemplate>
          <TemplateId xsi:nil="true" />
          <Name>Standard Server</Name>
          <Description>Basic server configuration</Description>
          <Quantity>1</Quantity>
          <Code>STD</Code>
          <NodeTemplate>
            <TemplateId xsi:nil="true" />
            <Name>Standard Server</Name>
            <Description>Basic server configuration</Description>
            <PrimaryVlan>{{int}}</PrimaryVlan>
            <Domain>{{primary}}</Domain>
            <RamSize>4</RamSize>
            <CpuCores>2</CpuCores>
            <Drives>
              <DriveParameter>
                <Letter>C</Letter>
                <Capacity>50</Capacity>
              </DriveParameter>
              <DriveParameter>
                <Letter>D</Letter>
                <Capacity>20</Capacity>
              </DriveParameter>
              <DriveParameter>
                <Letter>E</Letter>
                <Capacity>50</Capacity>
              </DriveParameter>
            </Drives>
            <VmTemplate>1NIC2012R2CLUST</VmTemplate>
            <ScomInstall>True</ScomInstall>
            <SccmInstall>True</SccmInstall>
          </NodeTemplate>
        </RoleTemplate>
      </Roles>
    </ServiceTemplate>
  </dbTemplates>
</ACME>

1 个答案:

答案 0 :(得分:0)

LatLngBounds.Builder builder = new LatLngBounds.Builder(); for(Location loc: locations) { MarkerOptions marker = new MarkerOptions().position(loc.lat, loc.lon); googleMap.addMarker(marker); builder.include(marker.getPosition()); } LatLngBounds bounds = builder.build(); CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, 5); googleMap.animateCamera(cameraUpdate); 上使用nodes(),您可以获得所有这些内容。优点是,你可以处理任何数字。

您想要的是并排结果。在这种情况下,您必须知道,您希望使用哪些字母并将其用作<DriveParameter> - 过滤器(请注意,XQuery区分大小写。以下解决方案仅适用于大写字母... < / p>

还有一个提示:如果您将XQuery称为CROSS APPLYA(ST)B(RO)等,则更容易阅读。然后,您可以致电C(RT)并避免重复ST.value(...)您的查询......

.C.value

- 查询

DECLARE @xml XML=
'<ACME>
  <dbTemplates>
    <ServiceTemplate xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <TemplateId>3205ac97-6396-4acb-8f93-5704297f1bbc</TemplateId>
      <Name>Basic Service</Name>
      <Description>Single Server Service</Description>
      <Roles>
        <RoleTemplate>
          <TemplateId xsi:nil="true" />
          <Name>Standard Server</Name>
          <Description>Basic server configuration</Description>
          <Quantity>1</Quantity>
          <Code>STD</Code>
          <NodeTemplate>
            <TemplateId xsi:nil="true" />
            <Name>Standard Server</Name>
            <Description>Basic server configuration</Description>
            <PrimaryVlan>{{int}}</PrimaryVlan>
            <Domain>{{primary}}</Domain>
            <RamSize>4</RamSize>
            <CpuCores>2</CpuCores>
            <Drives>
              <DriveParameter>
                <Letter>C</Letter>
                <Capacity>50</Capacity>
              </DriveParameter>
              <DriveParameter>
                <Letter>D</Letter>
                <Capacity>20</Capacity>
              </DriveParameter>
              <DriveParameter>
                <Letter>E</Letter>
                <Capacity>50</Capacity>
              </DriveParameter>
            </Drives>
            <VmTemplate>1NIC2012R2CLUST</VmTemplate>
            <ScomInstall>True</ScomInstall>
            <SccmInstall>True</SccmInstall>
          </NodeTemplate>
        </RoleTemplate>
      </Roles>
    </ServiceTemplate>
  </dbTemplates>
</ACME>';