我将在这里使用通用术语。
我有一组对象,每个对象都有多个属性将它们链接到主题。 Subject有一个通过另一个属性与之关联的整数值。
对于每个对象,我想以最大值检索其主题。
根据以下内容检索具有一个对象的最大值的主题非常简单:How do I make a SPARQL query to find the highest value for a property?。由于我想要主题本身(而不仅仅是它的价值),我使用了“获取所有主题,订购它们,限制1 ”的解决方案。
但是,我不能让这种方法适用于多个对象。我试过了:
SELECT ?object ?subject ?subMaxVal
WHERE {
?object a :Object.
{
SELECT ?subject (?value as ?subMaxVal)
WHERE {
?object :Predicate ?subject.
?subject :value ?value.
}
ORDER BY DESC(?value)
LIMIT 1
}
}
但这会返回不正确的结果。它找到?subMaxVal
的值,但随后使用数据集中的所有对象返回此值(即使此值仅适用于其中一个)。
我发现提到SPARQL子查询是在内部优先执行的。我无法解决如何构建查询以执行每个对象的子查询。
答案 0 :(得分:4)
我们的想法是先使用子SELECT
来获取每个对象的最大值。然后在外部查询中,此最大值用于获取主题:
@prefix : <http://ex.org/> .
:o1 :Predicate :s1 ; a :Object . :s1 :value 1 .
:o1 :Predicate :s2 ; a :Object . :s2 :value 2 .
:o1 :Predicate :s3 ; a :Object . :s3 :value 3 .
:o2 :Predicate :s2 ; a :Object . :s2 :value 2 .
:o2 :Predicate :s3 ; a :Object . :s3 :value 3 .
:o3 :Predicate :s2 ; a :Object . :s2 :value 2 .
:o3 :Predicate :s3 ; a :Object . :s3 :value 3 .
:o3 :Predicate :s4 ; a :Object . :s4 :value 3 .
PREFIX : <http://ex.org/>
SELECT ?object ?subject ?subMaxVal
WHERE {
?object a :Object.
?object :Predicate ?subject.
?subject :value ?subMaxVal.
# find the max value per object
{
SELECT ?object (MAX(?value) as ?subMaxVal)
WHERE {
?object :Predicate ?subject.
?subject :value ?value.
}
GROUP BY ?object
}
}
--------------------------------
| object | subject | subMaxVal |
================================
| :o2 | :s3 | 3 |
| :o3 | :s4 | 3 |
| :o3 | :s3 | 3 |
| :o1 | :s3 | 3 |
--------------------------------
如您所见,如果这些主题共享最大值,则此查询确实会返回单个对象的多个主题。值。在这种情况下,您可以获得这些主题的样本:
PREFIX : <http://ex.org/>
SELECT ?object (MIN(?subj) as ?subject) ?subMaxVal
WHERE {
?object a :Object.
?object :Predicate ?subj.
?subj :value ?subMaxVal.
# find the max value per object
{
SELECT ?object (MAX(?value) as ?subMaxVal)
WHERE {
?object :Predicate ?subject.
?subject :value ?value.
}
GROUP BY ?object
}
}
GROUP BY ?object ?subMaxVal
--------------------------------
| object | subject | subMaxVal |
================================
| :o1 | :s3 | 3 |
| :o3 | :s3 | 3 |
| :o2 | :s3 | 3 |
--------------------------------