XQuery 找到两个最大值
XQuery find two largest values
我有四个价值观会不断变化。我想从中获取一个字符串,其中包含其中两个最大的值 ("v1, v2"
)。它们可以按顺序排列,也可以单独排列。我不在乎。我尝试了多种不同的方法,但我不是这方面的专家,我就是想不通。我想出了如何使用 max()
函数获取序列中的最大值,但我还需要第二大值。
下面几乎是正确的,除了它没有处理最大值重复的情况(因此应该为两个值返回)。
declare variable $seq := (2,4,3,1); (: define the input sequence :)
max($seq), max($seq[. != max($seq)]) (: evaluate to maximum and max of values not equal
to the global maximum :)
如果您还想处理另一种情况,一种方法是:
(: from http://www.xqueryfunctions.com/xq/functx_sort-as-numeric.html :)
declare function local:sort-as-numeric
( $seq as item()* ) as item()* {
for $item in $seq
order by number($item)
return $item
};
(: define the input sequence :)
declare variable $seq := (2,4,3,1);
(: sort the sequence, then take the last and second-to-last values :)
local:sort-as-numeric($seq)[position()=(last()-1, last())]
...显然,如果您想要非数字排序,请将 order by number($item)
更改为 order by $item
。
这是从序列中获取最大 N 的通用方法。
declare function local:max-N(
$seq as item()*,
$N as xs:int
) as item()*
{
if ($N gt 0)
then
let $max := max($seq)[1]
return ($max, local:max-N($seq[. ne $max], $N - 1))
else ()
};
例如解决您描述的问题:
local:max-N(
(111, 22, 333, 4, 55, 66, 7, 88),
2)
=> (333, 111)
我有四个价值观会不断变化。我想从中获取一个字符串,其中包含其中两个最大的值 ("v1, v2"
)。它们可以按顺序排列,也可以单独排列。我不在乎。我尝试了多种不同的方法,但我不是这方面的专家,我就是想不通。我想出了如何使用 max()
函数获取序列中的最大值,但我还需要第二大值。
下面几乎是正确的,除了它没有处理最大值重复的情况(因此应该为两个值返回)。
declare variable $seq := (2,4,3,1); (: define the input sequence :)
max($seq), max($seq[. != max($seq)]) (: evaluate to maximum and max of values not equal
to the global maximum :)
如果您还想处理另一种情况,一种方法是:
(: from http://www.xqueryfunctions.com/xq/functx_sort-as-numeric.html :)
declare function local:sort-as-numeric
( $seq as item()* ) as item()* {
for $item in $seq
order by number($item)
return $item
};
(: define the input sequence :)
declare variable $seq := (2,4,3,1);
(: sort the sequence, then take the last and second-to-last values :)
local:sort-as-numeric($seq)[position()=(last()-1, last())]
...显然,如果您想要非数字排序,请将 order by number($item)
更改为 order by $item
。
这是从序列中获取最大 N 的通用方法。
declare function local:max-N(
$seq as item()*,
$N as xs:int
) as item()*
{
if ($N gt 0)
then
let $max := max($seq)[1]
return ($max, local:max-N($seq[. ne $max], $N - 1))
else ()
};
例如解决您描述的问题:
local:max-N(
(111, 22, 333, 4, 55, 66, 7, 88),
2)
=> (333, 111)