通过xquery与group相加

时间:2012-03-12 21:12:20

标签: sql xquery xquery-sql

我正在尝试将以下sql转换为

SELECT SUM((((1-Discount)*Quantity)*[Unit Price]))  AS AMOUNT 
FROM Orders 
LEFT JOIN [Order Details] 
    ON Orders.[Order ID] = [Order Details].[Order ID] 
WHERE ((([Order Date]) BETWEEN #1/1/2006# AND #2/1/2006#));

订单和订单详细信息具有1对多的关系(1与订单有关)

我目前的代码显示了每个订单详细信息的全价,但是不允许我将订单详细信息的每个总价值组合在一起以获得全部价值。

for $orderdetails in doc("Order Details.xml")/dataroot/Order_x0020_Details
let $order := doc("Orders.xml")/dataroot/Orders[OrderID = $orderdetails/OrderID]

where xs:dateTime($order/OrderDate/text()) gt xs:dateTime("1996-04-06T00:00:00") and  xs:dateTime($order/OrderDate/text()) lt xs:dateTime("1997-04-05T00:00:00")

return 
<Invoice_Amounts>
{
    $order/OrderID
}
<Amount>
{
 sum(((1 - xs:double($orderdetails/Discount)) * xs:double($orderdetails/UnitPrice)) * xs:double($orderdetails/Quantity))
}
</Amount>
</Invoice_Amounts>

Orders.xml

的示例
<OrderID>10248</OrderID>
        <CustomerID>WILMK</CustomerID>
        <EmployeeID>5</EmployeeID>
        <OrderDate>1996-07-04T00:00:00</OrderDate>
        <RequiredDate>1996-08-01T00:00:00</RequiredDate>
        <ShippedDate>1996-07-16T00:00:00</ShippedDate>
        <ShipVia>3</ShipVia>
        <Freight>32.38</Freight>
        <ShipName>Vins et alcools Chevalier</ShipName>
        <ShipAddress>59 rue de l&apos;Abbaye</ShipAddress>
        <ShipCity>Reims</ShipCity>
        <ShipPostalCode>51100</ShipPostalCode>
        <ShipCountry>France</ShipCountry>
    </Orders>
    <Orders>
        <OrderID>10249</OrderID>
        <CustomerID>TRADH</CustomerID>
        <EmployeeID>6</EmployeeID>
        <OrderDate>1996-07-05T00:00:00</OrderDate>
        <RequiredDate>1996-08-16T00:00:00</RequiredDate>
        <ShippedDate>1996-07-10T00:00:00</ShippedDate>
        <ShipVia>1</ShipVia>
        <Freight>11.61</Freight>
        <ShipName>Toms Spezialitäten</ShipName>
        <ShipAddress>Luisenstr. 48</ShipAddress>
        <ShipCity>Münster</ShipCity>
        <ShipPostalCode>44087</ShipPostalCode>
        <ShipCountry>Germany</ShipCountry>
    </Orders>

Order Details.xml的样本

    <OrderID>10248</OrderID>
<ProductID>11</ProductID>
<UnitPrice>14</UnitPrice>
<Quantity>12</Quantity>
<Discount>0</Discount>
</Order_x0020_Details>
<Order_x0020_Details>
<OrderID>10248</OrderID>
<ProductID>42</ProductID>
<UnitPrice>9.8</UnitPrice>
<Quantity>10</Quantity>
<Discount>0</Discount>
</Order_x0020_Details>
<Order_x0020_Details>
<OrderID>10248</OrderID>
<ProductID>72</ProductID>
<UnitPrice>34.8</UnitPrice>
<Quantity>5</Quantity>
<Discount>0</Discount>
</Order_x0020_Details>
<Order_x0020_Details>
<OrderID>10249</OrderID>
<ProductID>14</ProductID>
<UnitPrice>18.6</UnitPrice>
<Quantity>9</Quantity>
<Discount>0</Discount>
</Order_x0020_Details>

1 个答案:

答案 0 :(得分:0)

所以 - 据我所知,你已经知道如何进行连接,所以要关注的是sum操作。最简单的方法是使用for循环设置变量,然后使用该变量:

let $doc :=
    <docroot>
        <Order id="1">
            <Discount>0.05</Discount>
            <Quantity>3</Quantity>
            <UnitPrice>15</UnitPrice>
        </Order>
        <Order id="2">
            <Discount>0</Discount>
            <Quantity>15</Quantity>
            <UnitPrice>20</UnitPrice>
        </Order>
    </docroot>

(: collect the orders relevant to your query;
   in your "real" version you'll want to filter,
   or do your join, or whatever :)
let $orders := $doc/Order

(: generate a sequence containing the price for
   each such order :)
let $order_costs := 
    for $order in $orders
        return ((1.0 - xs:double($order/Discount))
                    * xs:double($order/UnitPrice)
                    * xs:double($order/Quantity))

(: generate your final result :)
return sum($order_costs)

您还可以通过在参数sum()中嵌入for循环来避免变量赋值:

return sum(for $order in $orders
           return ((1.0 - xs:double($order/Discount))
                    * xs:double($order/UnitPrice)
                    * xs:double($order/Quantity))