SQL Server XML格式

时间:2016-11-04 00:33:27

标签: sql sql-server xml

我已经坚持了这个问题差不多2天了......最底层的是我提出的问题,但我似乎无法正确地进行格式化。任何帮助将不胜感激。

问题在于:

--Axis data
create TABLE tmpPrimaryAxisLeaves 
(
     NodeID int, 
     NodeLabel nvarchar(max)
)

create TABLE tmpSecondaryAxisLeaves  
(
     NodeID int, 
     NodeLabel nvarchar(max)
)

create TABLE tmpTertiaryAxisLeaves 
(
     NodeID int, 
     NodeLabel nvarchar(max)
)

INSERT INTO tmpPrimaryAxisLeaves (NodeID, NodeLabel) 
    SELECT 1, 'North America' UNION
    SELECT 2, 'South America' UNION
    SELECT 3, 'EU' UNION
    SELECT 4, 'Africa' UNION
    SELECT 5, 'Russia'

INSERT INTO tmpSecondaryAxisLeaves (NodeID, NodeLabel) 
    SELECT 10, 'Peter Pan' UNION
    SELECT 20, 'Groot' UNION
    SELECT 30, 'Batman' 

INSERT INTO tmpTertiaryAxisLeaves (NodeID, NodeLabel) 
    SELECT 2, 'Shirts' UNION
    SELECT 4, 'Pants' UNION
    SELECT 6, 'Hats' 

--Contract data
create table tmpContracts 
(
     StartDate datetime, 
     EndDate datetime, 
     PrimaryAxisID int, 
     SecondaryAxisID int, 
     TertiaryAxisID int, 
     LanguageID int
)

INSERT INTO tmpContracts (StartDate, EndDate, PrimaryAxisID, SecondaryAxisID, TertiaryAxisID, LanguageID)
  SELECT '1/1/2010', '1/1/2018', 1, 20, 2, 1 UNION
  SELECT '1/1/2010', '1/1/2018', 1, 20, 2, 2 UNION
  SELECT '1/1/2010', '1/1/2018', 1, 20, 2, 5 UNION
  SELECT '1/1/2010', '1/1/2018', 1, 20, 6, 1 UNION
  SELECT '1/1/2010', '1/1/2018', 1, 20, 6, 2 UNION
  SELECT '1/1/2010', '1/1/2018', 1, 20, 6, 5 UNION
  SELECT '1/1/2011', '1/1/2020', 2, 20, 2, 1 UNION
  SELECT '1/1/2011', '1/1/2020', 2, 20, 2, 3 UNION
  SELECT '1/1/2011', '1/1/2020', 2, 20, 4, 1 UNION
  SELECT '1/1/2011', '1/1/2020', 2, 20, 4, 3 UNION
  SELECT '1/1/2011', '1/1/2020', 2, 20, 4, 5 UNION
  SELECT '1/1/2011', '1/1/2020', 3, 30, 2, 1 UNION
  SELECT '1/1/2011', '1/1/2020', 4, 30, 6, 1

--Langauges
create table tmpLanguages 
(
     LanguageID int, 
     Name nvarchar(100)
)

INSERT INTO tmpLanguages
   SELECT 1, 'English' UNION
   SELECT 2, 'Spanish' UNION
   SELECT 3, 'French' UNION
   SELECT 4, 'Russia' UNION
   SELECT 5, 'Dutch'

编写一个查询,该查询将采用上述数据并以下列格式返回XML,并在每个指示的位置使用正确的值(" [XXXXX]")结果应如下所示:

<AvailabiltyList>
  <PrimaryNode>
    <NodeID>[PrimaryAxis.NodeID]</NodeID>
    <NodeLabel>[PrimaryAxis.NodeLabel]</NodeLabel>
    <SecondaryAxis>
      <SecondaryNode>
        <NodeID>[SecondaryAxis.NodeID]</NodeID>
        <NodeLabel>[SecondaryAxis.NodeLabel]</NodeLabel>
        <TertiaryAxis>
          <TertiaryNode>
            <NodeID>[TertiaryAxis.NodeID]</NodeID>
            <NodeLabel>[TertiaryAxis.NodeLabel]</NodeLabel>
            <ContractData>
              <ContractDataPoint>
                <ContractStart>[Contracts.StartDate]</ContractStart>
                <ContractEnd>[Contracts.EndDate]</ContractEnd>
              </ContractDataPoint>
            </ContractData>
            <Languages>[Comma delimited list of languages for the matching contracts]</Languages>
          </TertiaryNode>
          <TertiaryNode>....</TertiaryNode>
          <TertiaryNode>....</TertiaryNode>
          <TertiaryNode>....</TertiaryNode>
        </TertiaryAxis>
      </SecondaryNode>
      <SecondaryNode>...</SecondaryNode>
      <SecondaryNode>...</SecondaryNode>
      <SecondaryNode>...</SecondaryNode>
      <SecondaryNode>...</SecondaryNode>
  </PrimaryNode>
  <PrimaryNode>...</PrimaryNode>
  <PrimaryNode>...</PrimaryNode>
  <PrimaryNode>...</PrimaryNode>
</AvailabilityList>

以下是我提出的建议。但我似乎无法正确地进行格式化。

select 
    PrimaryNode.NodeID as pnode,
    PrimaryNode.NodeLabel as plabel,
    SecondaryNode.NodeID as snode,
    SecondaryNode.NodeLabel as slabel,
    TertiaryNode.NodeID as tnode,
    TertiaryNode.NodeLabel as tlable, 
    ContractDataPoint.StartDate, 
    ContractDataPoint.EndDate
from 
    tmpContracts ContractDataPoint 
left join 
    tmpPrimaryAxisLeaves PrimaryNode on ContractDataPoint.PrimaryAxisID = PrimaryNode.NodeID
inner join 
    tmpSecondaryAxisLeaves SecondaryNode on     ContractDataPoint.SecondaryAxisID = SecondaryNode.NodeID
inner join 
    tmpTertiaryAxisLeaves TertiaryNode on        ContractDataPoint.TertiaryAxisID = TertiaryNode.NodeID
group by 
    PrimaryNode.NodeID, PrimaryNode.NodeLabel,
    SecondaryNode.NodeID, SecondaryNode.NodeLabel,
    TertiaryNode.NodeID, TertiaryNode.NodeLabel, 
    ContractDataPoint.StartDate, ContractDataPoint.EndDate
for xml auto, Root('AvailabiltyList'), Elements

我的结果:

<AvailabiltyList>
    <PrimaryNode>
        <pnode>1</pnode>
        <plabel>North America</plabel>
        <SecondaryNode>
          <snode>20</snode>
          <slabel>Groot</slabel>
      <TertiaryNode>
        <tnode>2</tnode>
        <tlable>Shirts</tlable>
        <ContractDataPoint>
          <StartDate>2010-01-01T00:00:00</StartDate>
          <EndDate>2018-01-01T00:00:00</EndDate>
        </ContractDataPoint>
      </TertiaryNode>
      <TertiaryNode>
        <tnode>6</tnode>
        <tlable>Hats</tlable>
        <ContractDataPoint>
          <StartDate>2010-01-01T00:00:00</StartDate>
          <EndDate>2018-01-01T00:00:00</EndDate>
        </ContractDataPoint>
      </TertiaryNode>
    </SecondaryNode>
  </PrimaryNode>
  <PrimaryNode>
    <pnode>2</pnode>
    <plabel>South America</plabel>
    <SecondaryNode>
      <snode>20</snode>
      <slabel>Groot</slabel>
      <TertiaryNode>
        <tnode>2</tnode>
        <tlable>Shirts</tlable>
        <ContractDataPoint>
          <StartDate>2011-01-01T00:00:00</StartDate>
          <EndDate>2020-01-01T00:00:00</EndDate>
        </ContractDataPoint>
      </TertiaryNode>
      <TertiaryNode>
        <tnode>4</tnode>
        <tlable>Pants</tlable>
        <ContractDataPoint>
          <StartDate>2011-01-01T00:00:00</StartDate>
          <EndDate>2020-01-01T00:00:00</EndDate>
        </ContractDataPoint>
      </TertiaryNode>
    </SecondaryNode>
  </PrimaryNode>
  <PrimaryNode>
    <pnode>3</pnode>
    <plabel>EU</plabel>
    <SecondaryNode>
      <snode>30</snode>
      <slabel>Batman</slabel>
      <TertiaryNode>
        <tnode>2</tnode>
        <tlable>Shirts</tlable>
        <ContractDataPoint>
          <StartDate>2011-01-01T00:00:00</StartDate>
          <EndDate>2020-01-01T00:00:00</EndDate>
        </ContractDataPoint>
      </TertiaryNode>
    </SecondaryNode>
  </PrimaryNode>
  <PrimaryNode>
    <pnode>4</pnode>
    <plabel>Africa</plabel>
    <SecondaryNode>
      <snode>30</snode>
      <slabel>Batman</slabel>
      <TertiaryNode>
        <tnode>6</tnode>
        <tlable>Hats</tlable>
        <ContractDataPoint>
          <StartDate>2011-01-01T00:00:00</StartDate>
          <EndDate>2020-01-01T00:00:00</EndDate>
        </ContractDataPoint>
      </TertiaryNode>
    </SecondaryNode>
  </PrimaryNode>
</AvailabiltyList>

1 个答案:

答案 0 :(得分:0)

您可以尝试这样的事情

创建一个udf来获取语言

CREATE FUNCATION udfAxisLanguage
(@pNodeId  INT
,@sNodeId  INT
,@tNodeId  INT
)
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE @retLang VARCHAR(100)   
select  
    @retLang = COALESCE(@retLang + ',','') + lang.name
from 
    tmpContracts ContractDataPoint 
left join 
    tmpPrimaryAxisLeaves PrimaryNode on ContractDataPoint.PrimaryAxisID = PrimaryNode.NodeID
inner join 
    tmpSecondaryAxisLeaves SecondaryNode on     ContractDataPoint.SecondaryAxisID = SecondaryNode.NodeID
inner join 
    tmpTertiaryAxisLeaves TertiaryNode on        ContractDataPoint.TertiaryAxisID = TertiaryNode.NodeID
inner join tmpLanguages lang on ContractDataPoint.languageid = lang.languageId
WHERE PrimaryNode.NodeID = @pNodeId
AND   SecondaryNode.NodeID = @sNodeId
AND   TertiaryNode.NodeID = @tNodeId
;

RETURN @retLang ;
END ;

现在在您的查询中使用上述udf,就像这样

select 
    PrimaryNode.NodeID as pnode,
    PrimaryNode.NodeLabel as plabel,
    SecondaryNode.NodeID as snode,
    SecondaryNode.NodeLabel as slabel,
    TertiaryNode.NodeID as tnode,
    TertiaryNode.NodeLabel as tlable, 
    ContractDataPoint.StartDate, 
    ContractDataPoint.EndDate,
    dbo.udfAxisLanguage(PrimaryNode.NodeID,SecondaryNode.NodeID,TertiaryNode.NodeID) Name
from 
    tmpContracts ContractDataPoint 
left join 
    tmpPrimaryAxisLeaves PrimaryNode on ContractDataPoint.PrimaryAxisID = PrimaryNode.NodeID
inner join 
    tmpSecondaryAxisLeaves SecondaryNode on     ContractDataPoint.SecondaryAxisID = SecondaryNode.NodeID
inner join 
    tmpTertiaryAxisLeaves TertiaryNode on        ContractDataPoint.TertiaryAxisID = TertiaryNode.NodeID
group by 
    PrimaryNode.NodeID, PrimaryNode.NodeLabel,
    SecondaryNode.NodeID, SecondaryNode.NodeLabel,
    TertiaryNode.NodeID, TertiaryNode.NodeLabel, 
    ContractDataPoint.StartDate, ContractDataPoint.EndDate
    ,dbo.udfAxisLanguage(PrimaryNode.NodeID,SecondaryNode.NodeID,TertiaryNode.NodeID)
for xml auto, Root('AvailabiltyList'), Elements