【问题标题】:SQL Server : Count of XML Elements By Element NameSQL Server:按元素名称计算 XML 元素的数量
【发布时间】:2018-02-15 00:03:33
【问题描述】:

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

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

【问题讨论】:

  • 为这三个记录提供预期结果
  • 最好给我们样本数据作为填充的临时表
  • 我更新了故事;抱歉,数字没有对齐。

标签: sql sql-server xml


【解决方案1】:

您需要先提取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;

【讨论】:

    【解决方案2】:

    您可以在通过 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-12
      相关资源
      最近更新 更多