SQL Server:按元素名称计算XML元素

时间:2017-09-06 13:10:16

标签: sql sql-server xml

我已经使用此查询成功获得了子元素的计数。

SELECT  
    raa.ApplicationXML.value('count(Root/ThirdParty/*)', 'Int') as [Bureau Count]
FROM 
    Table1 raa

但是,我想根据子元素的实际名称对此计数进行分组。

我的XML看起来像这样:

记录1:

<Root>
    <ThirdParty>
        <BureauRed />
        <BureauGreen />
        <BureauBlue />
    </ThirdParty>
</Root>

记录2:

<Root>
    <ThirdParty>
        <BureauRed />
        <BureauPurple />
        <BureauBlue />
    </ThirdParty>
</Root>

记录3:

<Root>
    <ThirdParty>
        <BureauGreen />
        <BureauRed />
        <BureauPurple />
        <BureauOrange />
        <BureauBlue />
    </ThirdParty>
</Root>

我不仅需要提取每个局的数量,而且还需要得到局的名称(BureauRed,BureauGreen,BureauBlue等)。当我尝试按计数分组时,我得到错误:

  

GROUP BY子句中不允许使用XML方法。

使用此查询:

SELECT  
    raa.ApplicationXML.value('count(Root/ThirdParty/*)', 'Int') as [Bureau Count]
FROM 
    Table1 raa
GROUP BY
    raa.ApplicationXML.value('count(Root/ThirdParty/*)', 'Int')

我如何获得该局的统计数据和名称?

我正在寻找这个结果:

Bureau         Count
============   =====
BureauRed      3
BureauGreen    2
BureauBlue     3
BureauPurple   2
BureauOrange   1

2 个答案:

答案 0 :(得分:0)

您需要首先提取Root/ThirdParty子元素,然后使用该派生表进行计数。

DECLARE @tv TABLE(x XML);

INSERT INTO @tv(x)VALUES(
N'<Root>
    <ThirdParty>
        <BureauRed />
        <BureauGreen />
        <BureauBlue />
    </ThirdParty>
</Root>'),(
N'<Root>
    <ThirdParty>
        <BureauRed />
        <BureauPurple />
        <BureauBlue />
    </ThirdParty>
</Root>'),(
N'<Root>
    <ThirdParty>
        <BureauGreen />
        <BureauRed />
        <BureauPurple />
        <BureauOrange />
        <BureauBlue />
    </ThirdParty>
</Root>');

WITH bureaus AS (
    SELECT 
        bureau=n.v.value('local-name(.)','NVARCHAR(256)')
    FROM
        @tv
        CROSS APPLY x.nodes('/Root/ThirdParty/*') AS n(v)
)
SELECT
    bureau,
    [count]=COUNT(*)
FROM
    bureaus
GROUP BY
    bureau
ORDER BY
    bureau;

答案 1 :(得分:0)

您可以在通过XQuery接收数据后进行分组:

DECLARE @xml1 xml = 
'<Root>
    <ThirdParty>
        <BureauRed />
        <BureauGreen />
        <BureauBlue />
    </ThirdParty>
</Root>';
DECLARE @xml2 xml = 
'<Root>
    <ThirdParty>
        <BureauRed />
        <BureauPurple />
        <BureauBlue />
    </ThirdParty>
</Root>';
DECLARE @xml3 xml = 
'<Root>
    <ThirdParty>
        <BureauGreen />
        <BureauRed />
        <BureauPurple />
        <BureauOrange />
        <BureauBlue />
    </ThirdParty>
</Root>';

DECLARE @temp TABLE (XmlData xml);

INSERT @temp VALUES (@xml1), (@xml2), (@xml3);

WITH cte AS
(
    SELECT n.value('local-name(.)', 'varchar(50)') nodeName
        FROM @temp t
        CROSS APPLY t.XmlData.nodes('/Root/ThirdParty/*') x(n)
)
SELECT nodeName, count(*) cnt
    FROM cte
    GROUP BY nodeName;

输出:

nodeName                                           cnt
-------------------------------------------------- -----------
BureauBlue                                         3
BureauGreen                                        2
BureauOrange                                       1
BureauPurple                                       2
BureauRed                                          3