Xquery顶级功能

时间:2010-11-14 01:12:33

标签: xquery

如何使用Xquery实现类似于TOP函数的SQL?换句话说,我怎样才能选择带有关系的前5个元素呢?这应该很简单,但我无法通过谷歌找到它。

我可能想要格式化的一些数据示例如下:

<?xml version="1.0"?>
<root>
    <value> 
        <a>first</a>
        <b>1</b>
    </value>
    <value> 
        <a>third</a>
        <b>3</b>
    </value>
    <value> 
        <a>second</a>
        <b>2</b>
    </value>
    <value> 
        <a>2nd</a>
        <b>2</b>
    </value>
</root>

我想用b对所有值进行排序并返回a。为了说明我的问题,请说我想返回带有关系的前两个值。

由于

5 个答案:

答案 0 :(得分:3)

对于提供的源XML文档

<root>
  <value> 
    <a>first</a>
    <b>1</b>
  </value>
  <value> 
    <a>third</a>
    <b>3</b>
  </value>
  <value> 
    <a>second</a>
    <b>2</b>
  </value>
  <value> 
    <a>2nd</a>
    <b>2</b>
  </value>
</root>

要获得前两个结果“有关系”,请使用

let $vals := 
  for $k in distinct-values(/*/*/b/xs:integer(.)) 
    order by $k
    return $k
 return
  for $a in /*/value[index-of($vals,xs:integer(b)) le 2]/a
      order by $a/../b/xs:integer(.)
    return $a  

评估此表达式时,会生成所需的正确结果

<a>first</a>
<a>second</a>
<a>2nd</a>

<强>解释

  1. 我们在$vals中指定/*/*/b的所有不同值的排序顺序,用作整数。这是必要的,因为无法保证函数 distinct-values() 以任何预定义的顺序生成其结果序列。另外,如果我们在排序之前没有将值转换为xs:integer,它们将被排序为字符串,这通常会产生不正确的结果。

  2. 然后我们只选择那些/*/value/a,其明确整数b-values的排序序列中的b-sibling索引小于或等于2

  3. 最后,我们需要按照b-sibling的整数值对结果进行排序,否则将按文档顺序选择

  4. 请注意

    目前只有此解决方案可为/*/*/b的任何整数值生成正确的排序结果

答案 1 :(得分:2)

要将序列过滤到前5个项目,请使用fn:position()功能:

$sequence[position() le 5]

请注意,当要过滤的序列是来自/步操作的节点集结果时,谓词将再次作用于最后一个轴。所以,也许你需要在parentesis之间包装那个表达式。

但是,要过滤“计算序列”(如排序或元组过滤条件),您需要使用FLWOR表达式的全部功能。

这个XQuery:

(for $value in /root/value
 order by $value/b
 return $value/a)[position() le 2]

输出:

<a>first</a><a>second</a>

注意:这是一种简单的排序。过滤器是最外层的表达式,因为这允许惰性avaluation。

这个XQuery:

for $key in (for $val in distinct-values(/root/value/b)
             order by xs:integer($val)
             return $val)[position() le 2]
return /root/value[b=$key]/a

输出:

<a>first</a><a>second</a><a>2nd</a>

注意:首先按键,然后返回前两个键的所有结果。

修改:添加了显式整数转换。

答案 2 :(得分:1)

您可以在节点上使用XPath,并将上限作为索引

    <one>
  <two>a</two>
  <two>b</two>
  <two>c</two>
  <two>d</two>
  <two>e</two>
  <two>f</two>
  <two>g</two>
  <two>h</two>
   </one>

然后

$xml_data/one/two[ 1 to 5 ]

$xml_data/one/two[ some_number to fn:last() ]

答案 3 :(得分:0)

使用示例输入

<one>
  <two>a</two>
  <two>b</two>
  <two>c</two>
  <two>d</two>
  <two>e</two>
  <two>f</two>
  <two>g</two>
  <two>h</two>
</one>

以下是获取前五行的一种方法:

for $two at $index in /one/two
  where $index <= 5
  return $two

答案 4 :(得分:-1)

在MySQL方言中,它不是TOP,而是LIMIT。当你谷歌“限制xquery”时,你会发现:

http://osdir.com/ml/text.xml.exist/2004-02/msg00214.html

http://osdir.com/ml/text.xml.exist/2004-08/msg00115.html