2012-03-12 89 views
0

我尝试转换下面的SQL总和与GROUP BY的XQuery

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是订单)

我目前拥有的代码显示每个订单详细信息的全部价格,但是不会允许我将每个订单详细信息的总价值合并在一起以获取完整价值。样品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> 

打样订单的`的

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> 

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> 
+0

您定位的是哪个版本的标准? (XQuery 3.0通过支持显式分组)。 – 2012-03-12 21:13:20

+0

如果代码样本被减少到与这个特定问题相关的最小值,这将是有帮助的;现在通过阅读相关细节需要做很多工作。 – 2012-03-12 21:14:14

+0

xml文档超过20000行,因此我只提出了一些示例文本,但是我在XML Spy中使用了X Query 1 – 2012-03-12 21:55:20

回答

0

所以 - 据我所知,你已经知道该怎么做的加入,所以要重点关注的是总和操作。要做到这一点,最简单的方法是使用一个循环设置一个变量,然后您可以使用:

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) 

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

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

查尔斯,我appretiate你的答案,但让$订单标记“XQuery验证错误!” 意外的令牌 - “let $ orders:= $ orderdeta” – 2012-03-12 22:25:23

+0

嗯,我在这里没有可用的XQuery 1.0引擎,它在BaseX上工作正常,所以我需要以后再回复你 – 2012-03-12 22:26:55

+0

@PeterRoche我给出的确切查询没有'let $ orders:= $ orderdeta'行,并且已经验证可以在XMLSpy上工作。 – 2012-03-13 13:41:36