XQuery - 对序列中的元素进行数学计算并聚合结果
XQuery - Doing math on elements within a sequence and aggregating results
我试图在两个 XML 元素的乘积中执行 XQuery 求和函数,但很难避免元素序列中的迭代。例如,考虑这种情况:
示例数据:
<Orders>
<Order>
<OrderKey>1</OrderKey>
<LineItem>
<LineNumber>1</LineNumber>
<Quantity>41</Quantity>
<ExtendedPrice>70848.0000</ExtendedPrice>
<Discount>0.0913</Discount>
<Tax>0.0663</Tax>
<ReturnFlag>A</ReturnFlag>
<LineStatus>F</LineStatus>
<ShipDate>1994-09-03</ShipDate>
</LineItem>
<LineItem>
<LineNumber>2</LineNumber>
<Quantity>44</Quantity>
<ExtendedPrice>64372.0000</ExtendedPrice>
<Discount>0.0674</Discount>
<Tax>0.0145</Tax>
<ReturnFlag>A</ReturnFlag>
<LineStatus>F</LineStatus>
<ShipDate>1994-08-18</ShipDate>
</LineItem>
<LineItem>
<LineNumber>3</LineNumber>
<Quantity>41</Quantity>
<ExtendedPrice>64247.0000</ExtendedPrice>
<Discount>0.0396</Discount>
<Tax>0.0466</Tax>
<ReturnFlag>R</ReturnFlag>
<LineStatus>F</LineStatus>
<ShipDate>1994-10-21</ShipDate>
</LineItem>
</Order>
. . .
</Orders>
XQuery:
<results> {
for $lineitem in collection("tpch")/Orders/Order/LineItem
let $returnflag := $lineitem/ReturnFlag
let $linestatus := $lineitem/LineStatus
where $lineitem/ShipDate <= "1998-08-31"
group by $returnflag, $linestatus
order by $returnflag, $linestatus
return
<record>
<l_returnflag>{$returnflag}</l_returnflag>
<l_linestatus>{$linestatus}</l_linestatus>
<sum_qty>{sum($lineitem/Quantity)}</sum_qty>
<sum_base_price>{sum($lineitem/ExtendedPrice)}</sum_base_price>
<sum_disc_price>{sum($lineitem/ExtendedPrice*(1-$lineitem/Discount))}</sum_disc_price>
<sum_charge>{sum($lineitem/ExtendedPrice*(1-$lineitem/Discount)*(1+$lineitem/Tax))}</sum_charge>
<avg_qt>{avg($lineitem/Quantity)}</avg_qt>
<avg_price>{avg($lineitem/ExtendedPrice)}</avg_price>
<avg_disc>{avg($lineitem/Discount)}</avg_disc>
<count_order>{count($lineitem)}</count_order>
</record>
} </results>
BaseX 输出:
[XPTY0004] 预期项目,找到的序列:(元素 ExtendedPrice {...},......
当我删除 "sum_disc_price ..." 和 "sum_charge ..." 结果行时,查询运行正常。
我的问题:
考虑到这个数据集模型,我如何在不改变其语义的情况下编写这个查询?
发生此错误是因为您使用的运算(如乘法)恰好接受两个参数,并在一侧或两侧传递一个序列。为了说明错误的含义——你得到完全相同的东西 运行:
(1,2,3) * 2
由于您的目标是在聚合结果之前将 $lineitem
序列(由于 group by
运算符而产生的序列)内的每个 LineItem
的值相乘,因此您可以使用fn:for-each-pair
。使用匿名函数实现,可以执行以下操作:
<sum_disc_price>{sum(fn:for-each-pair(
$lineitem/ExtendedPrice, $lineitem/Discount,
function ($price, $discount) as xs:double {
xs:double($price) * (1 - xs:double($discount))
}(?,?)))}</sum_disc_price>
我试图在两个 XML 元素的乘积中执行 XQuery 求和函数,但很难避免元素序列中的迭代。例如,考虑这种情况:
示例数据:
<Orders>
<Order>
<OrderKey>1</OrderKey>
<LineItem>
<LineNumber>1</LineNumber>
<Quantity>41</Quantity>
<ExtendedPrice>70848.0000</ExtendedPrice>
<Discount>0.0913</Discount>
<Tax>0.0663</Tax>
<ReturnFlag>A</ReturnFlag>
<LineStatus>F</LineStatus>
<ShipDate>1994-09-03</ShipDate>
</LineItem>
<LineItem>
<LineNumber>2</LineNumber>
<Quantity>44</Quantity>
<ExtendedPrice>64372.0000</ExtendedPrice>
<Discount>0.0674</Discount>
<Tax>0.0145</Tax>
<ReturnFlag>A</ReturnFlag>
<LineStatus>F</LineStatus>
<ShipDate>1994-08-18</ShipDate>
</LineItem>
<LineItem>
<LineNumber>3</LineNumber>
<Quantity>41</Quantity>
<ExtendedPrice>64247.0000</ExtendedPrice>
<Discount>0.0396</Discount>
<Tax>0.0466</Tax>
<ReturnFlag>R</ReturnFlag>
<LineStatus>F</LineStatus>
<ShipDate>1994-10-21</ShipDate>
</LineItem>
</Order>
. . .
</Orders>
XQuery:
<results> {
for $lineitem in collection("tpch")/Orders/Order/LineItem
let $returnflag := $lineitem/ReturnFlag
let $linestatus := $lineitem/LineStatus
where $lineitem/ShipDate <= "1998-08-31"
group by $returnflag, $linestatus
order by $returnflag, $linestatus
return
<record>
<l_returnflag>{$returnflag}</l_returnflag>
<l_linestatus>{$linestatus}</l_linestatus>
<sum_qty>{sum($lineitem/Quantity)}</sum_qty>
<sum_base_price>{sum($lineitem/ExtendedPrice)}</sum_base_price>
<sum_disc_price>{sum($lineitem/ExtendedPrice*(1-$lineitem/Discount))}</sum_disc_price>
<sum_charge>{sum($lineitem/ExtendedPrice*(1-$lineitem/Discount)*(1+$lineitem/Tax))}</sum_charge>
<avg_qt>{avg($lineitem/Quantity)}</avg_qt>
<avg_price>{avg($lineitem/ExtendedPrice)}</avg_price>
<avg_disc>{avg($lineitem/Discount)}</avg_disc>
<count_order>{count($lineitem)}</count_order>
</record>
} </results>
BaseX 输出:
[XPTY0004] 预期项目,找到的序列:(元素 ExtendedPrice {...},......
当我删除 "sum_disc_price ..." 和 "sum_charge ..." 结果行时,查询运行正常。
我的问题: 考虑到这个数据集模型,我如何在不改变其语义的情况下编写这个查询?
发生此错误是因为您使用的运算(如乘法)恰好接受两个参数,并在一侧或两侧传递一个序列。为了说明错误的含义——你得到完全相同的东西 运行:
(1,2,3) * 2
由于您的目标是在聚合结果之前将 $lineitem
序列(由于 group by
运算符而产生的序列)内的每个 LineItem
的值相乘,因此您可以使用fn:for-each-pair
。使用匿名函数实现,可以执行以下操作:
<sum_disc_price>{sum(fn:for-each-pair(
$lineitem/ExtendedPrice, $lineitem/Discount,
function ($price, $discount) as xs:double {
xs:double($price) * (1 - xs:double($discount))
}(?,?)))}</sum_disc_price>