简体   繁体   中英

XQuery - count + value of node

i have a small problem with getting count of something and value of parent node for it. Actually xml schema looks like that:

<car> <carID> 1 </car> <fixes> <fix> <fixID> 1 </fixID> </fix> <fix> <fixID> 2 </fixID> </fix> </fixes> </car>

well more or less... what im trying to achieve is: by using XQuery (and thats important part) i need to return how many fixes each car has (i know that in example there is just one car). So i need in result something like 1 2 or something like that. Any help would be greatly appreciated

Edit: <car> <carID> 1 </car> <departmentID> 1 </departmentID> <fixes> <fix> <fixID> 1 </fixID> </fix> <fix> <fixID> 2 </fixID> </fix> </fixes> </car>

Now id like something a bit more troublesome ;/ I have XMLcolumn in sql server which hold sqldocument for car in a separate rows, so one row one . What im trying to do further on is to get carID for each department wich most amount of fixes. Any clue?;/

After fixing the closing </carID> tag, you can apply the xpath count aggregate to return the count of fixes:

DECLARE @xml XML =
'<car>
     <carID> 1 </carID>
    <fixes>
     <fix>
      <fixID> 1 </fixID>
      <fixID> 2 </fixID>
     </fix>
    </fixes>
 </car>';


SELECT
  Nodes.node.value('(carID)[1]', 'int') AS Car,
  Nodes.node.value('count(fixes/fix/fixID)', 'int') AS Fixes
FROM
  @xml.nodes('//car') AS Nodes(node);

SqlFiddle example here

Edit
Update for OP's new Question.

You need to use CROSS APPLY to apply the xml scraping to a column for all rows in a table. Once you know how to project data out of an Xml Column, the rest becomes a simple matter of using successive Sql projections to move to the end result:

WITH cteCarFixes AS
(
    SELECT
      Nodes.node.value('(carID)[1]', 'int') AS CarId,
      Nodes.node.value('(departmentID)[1]', 'int') AS DepartmentId,
      Nodes.node.value('count(fixes/fix/fixID)', 'int') AS Fixes
    FROM
        CarFixes cf
        CROSS APPLY cf.SomeXml.nodes('//car') as Nodes(node)
),
cteRankedCarFixes AS
(
    SELECT CarId, DepartmentId, Fixes,
        ROW_NUMBER() OVER(PARTITION BY DepartmentId ORDER BY Fixes DESC) AS Ranking
    FROM
        cteCarFixes cf
)
SELECT DepartmentId, CarId, Fixes
    FROM
        cteRankedCarFixes
    WHERE
        Ranking = 1

Updated SqlFiddle here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM