XQuery
Priscilla Walmsley (pwalmsley@datypic.com)
ISBN: 0596006349
1st edition, , O'Reilly Media, Inc.
Chapter 7: Sorting and grouping
for $item in doc("order.xml")//item order by $item/@num return $item
for $item in doc("order.xml")//item order by $item/@dept, $item/@num return $item
declare default order empty greatest; for $item in doc("order.xml")//item order by $item/@color return $item
let $sortedProds := for $prod in doc("catalog.xml")//product order by $prod/number return $prod for $prodName in $sortedProds/name return <li>{string($prodName)}</li>
for $prod in doc("catalog.xml")//product order by $prod/number return <li>{string($prod/name)}</li>
let $prods := doc("catalog.xml")//product for $prod in $prods where $prod << $prods[@dept = $prod/@dept][last()] return $prod
unordered( for $item in doc("order.xml")//item, $product in doc("catalog.xml")//product where $item/@num = $product/number return <item number="{$item/@num}" name="{$product/name}" quantity="{$item/@quantity}"/> )
unordered { for $item in doc("order.xml")//item, $product in doc("catalog.xml")//product where $item/@num = $product/number return <item number="{$item/@num}" name="{$product/name}" quantity="{$item/@quantity}"/> }
for $d in distinct-values(doc("order.xml")//item/@dept) let $items := doc("order.xml")//item[@dept = $d] order by $d return <department code="{$d}">{ for $i in $items order by $i/@num return $i }</department>
for $d in distinct-values(doc("order.xml")//item/@dept) let $items := doc("order.xml")//item[@dept = $d] order by $d return <department code="{$d}" numItems="{count($items)}" distinctItemNums="{count(distinct-values($items/@num))}" totQuant="{sum($items/@quantity)}"/>
declare namespace functx = "http://www.functx.com"; declare function functx:max-string ($stringSeq as xs:string*) as xs:string?{ max($stringSeq) }; (: Example call :) functx:max-string(doc("order.xml")//item/@dept)
declare namespace functx = "http://www.functx.com"; declare function functx:min-non-empty-string ($stringSeq as xs:string*) as xs:string? { min($stringSeq[. != '']) }; (: Example call :) functx:min-non-empty-string(doc("order.xml")//item/@dept)
declare namespace functx = "http://www.functx.com"; declare function functx:avg-empty-is-zero ($allNodes as node()*, $values as xs:anyAtomicType*) as xs:double { if (empty($allNodes)) then 0 else sum($values[. != ""]) div count($allNodes) }; (: Example call :) let $prods := doc("prices.xml")//prod return (functx:avg-empty-is-zero($prods, $prods/discount))
let $allItems := doc("order.xml")//item for $d in distinct-values($allItems/@dept) for $n in distinct-values($allItems[@dept = $d]/@num) let $items := $allItems[@dept = $d and @num = $n] order by $d, $n return <group dept="{$d}" num="{$n}" numItems="{count($items)}" totQuant="{sum($items/@quantity)}"/>
let $allItems := doc("order.xml")//item for $d in distinct-values($allItems/@dept) for $n in distinct-values($allItems/@num) let $items := $allItems[@dept = $d and @num = $n] where sum($items/@quantity) > 1 order by count($items) return if (exists($items)) then <group dept="{$d}" num="{$n}" numItems="{count($items)}" totQuant="{sum($items/@quantity)}"/> else ()