Question

Consider this table structure in Sql Server:

ID - uniqueidentifier
Params - xml

and rows in following format:

<!--ROW1 xml column content-->
<Params>
  <Module>
    <ModuleName>Module1</ModuleName>
  </Module>
  <Module>
    <ModuleName>Module2</ModuleName>
  </Module>
</Params>

<!--ROW2 xml column content-->
<Params>
    <Module>
        <ModuleName>Module1</ModuleName>
    </Module>
</Params>

Expected output (the sum of all occurrences of each element across the table):

_______________
| Module1 | 2 |
| Module2 | 1 |
|_____________|

Count of elements Module is 0..n in each row. I was trying to create stored procedure which returns multiple rows for each xml field input and then contribute results from each row into temp table but I had not luck with finding correct syntax. Can somebody refer to relevant resource or show some little snippet how to deal with it? Thanks for any hint provided.

Was it helpful?

Solution

You can apply some xquery to grab the Module Names and then count them with a GROUP BY:

SELECT ModuleName, COUNT(*) AS NumOccurrences
FROM
(
   SELECT
     Nodes.node.value('(ModuleName)[1]', 'varchar(50)') AS ModuleName
   FROM
       Modules m
       cross apply m.Params.nodes('//Module') as Nodes(node)
) x
GROUP BY ModuleName;

(Unfortunately, we can't group directly on xml, hence the need for the derived table)

SqlFiddle here

OTHER TIPS

Further to Stuart's answer, you can use the over clause

select distinct 
       t.x.value('.','varchar(50)'), 
       COUNT(*) over (partition by t.x.value('.','varchar(50)'))  
from yourtable 
    cross apply x.nodes('/Params/Module/ModuleName') t(x)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top