过滤平均值计算在哪里不起作用

时间:2017-11-01 01:19:30

标签: xquery

我正在尝试将avg(...)函数与where子句一起使用,但它不起作用:

let $x := doc("boats.xml")/boats/boat/price
           where $x < 100000
           return avg($x)

我试图找到所有小于100k的船的平均值

let $x := doc("boats.xml")/boats/boat/price
           return avg($x)

该代码适用于所有船只。为什么第一个不适用于小于100k的船只?

这也不起作用。它给了我一个低于100k的价格清单:

 for $x in doc("boats.xml")/boats/boat
                    where $x/price<100000
                    return avg($x/price)

2 个答案:

答案 0 :(得分:4)

通过返回$x而不是计算平均值,可以轻松揭示问题:您的第一个查询将$x声明为所有价格的序列(因此我$x(50000, 80000, 150000)以下示例文档)。 $x < 100000因此(50000, 80000, 150000) < 100000以基于集合的方式进行评估,并且如果序列中的任何元素小于100000,则验证为true; avg($x)最终再次获取原始列表并计算其平均值。

您的第三个查询是预期解决方案(并正确过滤)的一个很好的起点,但是因为您计算每个奖项的平均奖金而不是所有奖金的实际平均值而失败。

由于您没有提供示例输入,我定义了以下内容:

let $boats := document {
  <boats>
    <boat>
      <price>50000</price>
    </boat>
    <boat>
      <price>80000</price>
    </boat>
    <boat>
      <price>150000</price>
    </boat>
  </boats>
}

return avg(
  for $boat in $boats/boats/boat
  where $boat/price < 100000
  return $boat/price
)

此查询返回所提供输入的预期值65000。

答案 1 :(得分:0)

对于像这样的查询,使用XQuery的XPath子集通常更简单,而不是使用FLWOR表达式。这只是

avg(doc("boats.xml")/boats/boat/price[. < 100000])

或者我非常喜欢XPath 3.1管道语法

doc("boats.xml")/boats/boat/price[. < 100000] => avg()