如何使用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。为了说明我的问题,请说我想返回带有关系的前两个值。
由于
答案 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>
<强>解释强>:
我们在$vals
中指定/*/*/b
的所有不同值的排序顺序,用作整数。这是必要的,因为无法保证函数 distinct-values()
以任何预定义的顺序生成其结果序列。另外,如果我们在排序之前没有将值转换为xs:integer
,它们将被排序为字符串,这通常会产生不正确的结果。
然后我们只选择那些/*/value/a
,其明确整数b-values
的排序序列中的b-sibling索引小于或等于2 。
最后,我们需要按照b-sibling的整数值对结果进行排序,否则将按文档顺序选择
请注意:
目前只有此解决方案可为/*/*/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
和