如何在SPARQL中对值进行排序?

如何在SPARQL中对值进行排序?,sparql,Sparql,我想使用SPARQL创建观察结果的排名。假设我有: @prefix : <http://example.org#> . :A :value 60 . :B :value 23 . :C :value 89 . :D :value 34 . @前缀:。 :A:值为60。 :B:值23。 :C:value 89。 :D:值34。 排名应该是:C=1(最高),:A=2,:D=3,:B=4。到目前为止,我能够使用以下查询解决此问题: 前缀: 前缀rdf: 选择?x?v?排名{ ?x:值

我想使用SPARQL创建观察结果的排名。假设我有:

@prefix : <http://example.org#> .

:A :value 60 .
:B :value 23 .
:C :value 89 .
:D :value 34 .
@前缀:。
:A:值为60。
:B:值23。
:C:value 89。
:D:值34。
排名应该是:C=1(最高),:A=2,:D=3,:B=4。到目前为止,我能够使用以下查询解决此问题:

前缀:
前缀rdf:
选择?x?v?排名{
?x:值?v。
{按顺序选择(组_CONCAT(?x;separator=”“){
{SELECT?x{
?x:值?v。
}按描述排序(?v)
}
}
}
绑定(str(?x)为?xName)
绑定(strbefore(?ordered,?xName)与之前一样)
绑定((strlen(?before)/strlen(?xName))+1 as?排名)
}按顺序排列

但是,只有当
?x
的URI具有相同的长度时,该查询才起作用。更好的解决方案是在PHP中使用类似于
strpos
的函数,或者在Java中使用类似于
isIndexOf
的函数,但据我所知,它们在SPARQL 1.1中不可用。有更简单的解决方案吗?

一种方法是将小于或等于某个值的值的数量作为该值的排序。对于较大的数据集,这可能效率低下,因为对于每个值,它必须检查所有其他值。但它不需要字符串操作

前缀:
选择?x?v(计数(*)作为?排名),其中{
?x:值?v。
[]:值?u。

滤器(?v你能详细说明你想要创建什么吗?或者显示你编写的查询产生了什么吗?内部的select查询已经对结果进行了排序,所以你已经可以对结果进行排序了。外部查询执行一系列字符串操作,看看它们产生的结果的示例会有很大帮助。哦,我想我看到了你的想法询问,您希望结果是,例如,
C 89 1;A 60 2;D 34 3;B 23 4
。感谢您的回答。这是一个不同于我提出的解决方案,尽管正如您所说,我不确定它对于大型数据集是否非常有效。虽然我的示例很短,但我的实际应用程序可以有大约100个观察结果,并使用您的方法它意味着100个子查询。无论如何,一旦我准备好了完整的数据集,我会将你的解决方案与我上面写的解决方案进行比较。@Labra我刚刚生成了更多的样本数据,在1000个元素上,我的答案大约需要4.5秒,而你的原始答案大约需要2.5-2.8秒。我的answe说,只有100个元素,差异更小r大约需要1.8秒,而您的需要1.5秒。@Labra在可重用性方面,我要指出,在我第一次生成示例数据之后,您的查询给出了一些奇怪的结果。我花了一段时间才记住,您的查询要求所有资源都有URI,其字符串形式都是相同的长度。我必须调整数据生成器好吧,太好了!在我的特殊问题中,资源是由3个字母的iso代码标识的国家的URI,所以我知道它们的长度相同:).但正如您所说,您的解决方案更一般,可以应用于任何情况。然而,我很惊讶这个看似简单的问题在SPARQL中如此难以表达…@Labra嗯,我不知道我提供的解决方案必然“如此困难”;只是当您可以利用数据的特定属性时(例如,IRIs具有相同的长度),利用优化的解决方案有点复杂。像
strpos
这样的东西当然会很方便。您是否使用您控制的端点?向其添加扩展可能并不那么难…
---------------------
| x  | v  | ranking |
=====================
| :C | 89 | 1       |
| :A | 60 | 2       |
| :D | 34 | 3       |
| :B | 23 | 4       |
---------------------