我在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"
。
答案 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)