从MS SQL中的多个元素返回XML

时间:2016-12-16 14:01:13

标签: sql-server xml

我在MS SQL表中存储了以下XML。

<CustomerStrategy>
  <ChampionChallenger  GroupId="BureauPhoneTest" IsChampion="1" StrategyName="New Bureau Phone Champion" IsSelected="true" />
  <ChampionChallenger GroupId="BureauPhoneTest" IsChampion="0"  StrategyName="New Bureau Phone Challenger" IsSelected=""/>
</CustomerStrategy>

我正在寻找那些IsChampion = "0"IsSelected="true"GroupID="BureauPhoneTest"的人。 CustomerStrategy元素中可能还有其他冠军挑战者元素。

如何构建我的SQL只返回IsChampion = "0"IsSelected="true"以及GroupID="BureauPhoneTest"

2 个答案:

答案 0 :(得分:1)

您可以直接使用XML,如:

DECLARE @x TABLE (
    id int,
    xmlField xml
)

INSERT INTO @x VALUES
(1, '<CustomerStrategy>
  <ChampionChallenger  GroupId="BureauPhoneTest" IsChampion="1" StrategyName="New Bureau Phone Champion" IsSelected="true" />
  <ChampionChallenger GroupId="BureauPhoneTest" IsChampion="0"  StrategyName="New Bureau Phone Challenger" IsSelected=""/>
</CustomerStrategy>'),
(2, '<CustomerStrategy>
  <ChampionChallenger  GroupId="BureauPhoneTest" IsChampion="1" StrategyName="New Bureau Phone Champion" IsSelected="true" />
  <ChampionChallenger GroupId="BureauPhoneTest" IsChampion="0"  StrategyName="New Bureau Phone Challenger" IsSelected="true"/>
</CustomerStrategy>')


SELECT DISTINCT x.id
FROM @x x
CROSS APPLY (
    SELECT xmlField
    FROM xmlField.nodes('/CustomerStrategy/ChampionChallenger') as t(c)
    WHERE t.c.value('@IsChampion','bit') = 0 
            and t.c.value('@IsSelected','nvarchar(6)') = 'true'
            and t.c.value('@GroupId','nvarchar(50)') ='BureauPhoneTest'         
    ) as t

这将返回2。我添加了一个字符串,其中包含所有必需的条件。

答案 1 :(得分:1)

最好将.nodes()内的过滤器视为XQuery表达式。

特别是对于大型XML,首先阅读所有内容是一种过度杀伤,只是为了在最后过滤它。

以下内容将返回NULL表示id = 1,一个XML表示id = 2,两个表项表示id = 3:

DECLARE @tbl TABLE (id int,xmlField xml);
INSERT INTO @tbl VALUES
(1, '<CustomerStrategy>
  <ChampionChallenger  GroupId="BureauPhoneTest" IsChampion="1" StrategyName="New Bureau Phone Champion" IsSelected="true" />
  <ChampionChallenger GroupId="BureauPhoneTest" IsChampion="0"  StrategyName="New Bureau Phone Challenger" IsSelected=""/>
</CustomerStrategy>'),
(2, '<CustomerStrategy>
  <ChampionChallenger  GroupId="BureauPhoneTest" IsChampion="1" StrategyName="New Bureau Phone Champion" IsSelected="true" />
  <ChampionChallenger GroupId="BureauPhoneTest" IsChampion="0"  StrategyName="New Bureau Phone Challenger" IsSelected="true"/>
</CustomerStrategy>'),
(3, '<CustomerStrategy>
  <ChampionChallenger  GroupId="BureauPhoneTest" IsChampion="0" StrategyName="New Bureau Phone Champion" IsSelected="true" />
  <ChampionChallenger GroupId="BureauPhoneTest" IsChampion="0"  StrategyName="New Bureau Phone Challenger" IsSelected="true"/>
</CustomerStrategy>');

SELECT t.id
      ,Filtered.query('.') AS FilteredNodes
FROM @tbl AS t
OUTER APPLY xmlField.nodes(N'/CustomerStrategy/ChampionChallenger[@IsChampion eq "0" and @IsSelected eq "true" and @GroupId eq "BureauPhoneTest"]') AS A(Filtered)