Ceci est un défaut majeur dans XQuery 1.0, et pour cette raison un groupe par clause a été ajoutée dans XQuery 1.1, ils ont ajouté un groupe par article, de sorte que votre requête ressemblerait à ceci:
for $orderDetails in doc('orderDetails.xml')//OrderDetails)
let $orderId = $orderDetails/OrderID
let $orderCost = $orderDetails/Quantity * $orderDetails/UnitPrice
group by $orderId
let $totalValue := sum($orderCost)
return <order id="{$orderId}" totalValue="{$totalValue}" />
Malheureusement, XQuery 1.1 n'est encore qu'un brouillon de travail et peu d'implémentations sont disponibles.
Notre implémentation (XQSharp) essaye de repérer le motif que vous avez utilisé et de faire le groupe plus efficacement (cela apparaît comme un group-by dans le plan de requête). Malheureusement, notre implémentation ne repère pas un groupe dans votre cas particulier.
Le premier problème est différences de boîtier ("orderdetails.xml" vs "orderDetails.xml", //orderDetails
vs //OrderDetails
) - Je suppose que ce ne sont que des fautes de frappe.
Le plus gros problème est que ce que vous avez écrit n'est pas un groupe trivial! Sauf si vous utilisez un schéma qui indique le contraire, l'analyse statique ne peut pas déterminer que chaque nœud a exactement un OrderID, et la valeur atomisée de OrderID peut avoir plus d'un élément (s'il a une liste comme type de schéma). Cela signifie que l'analyse statique de distinct-values(doc('orderDetails.xml')//orderDetails/OrderID)
ne peut pas déterminer que chaque nœud a exactement une clé.
Pour résoudre ce votre requête peut être écrite comme suit:
for $orderId in distinct-values(doc("orderDetails.xml")/OrderDetails/exactly-one(OrderID/data(.)))
let $totalValue :=
sum(
for $detail in doc("orderDetails.xml")/OrderDetails[exactly-one(OrderID/data(.)) = $orderId]
return $detail/Quantity * $detail/UnitPrice
)
return <order id="{$orderId}" totalValue="{$totalValue}" />
Cette requête a alors la même sémantique en tant que groupe par et doit être optimisé en tant que tel. En l'occurrence, cela ne fonctionne toujours pas dans un groupe de XQSharp, donc j'ai classé cela comme un bug contre notre logiciel. Que XmlSpy effectue cette optimisation ou non, je ne pourrais pas dire.