我有一个返回重复项的sparql查询,我希望它只在其中一个值(subjectID)上清理它们。与DISTINCT不同,DISTINCT似乎为所选值的组合找到了唯一值,而不是仅针对其中一个参数。 我看到有人在这里建议group by,但是如果我在group by之后列出所有参数(我的sparql端点抱怨,例如SELECT中的非组键变量:?占用),这似乎只适用。 我尝试运行内部选择,但它似乎不适用于此特定查询。所以可能是查询本身的问题(livingIn可选的值似乎导致重复)?
虽然在SPARQL学习曲线的早期阶段对关系数据库感到满意,所以请随意解释显而易见的原因! :)
select distinct
?subjectID ?englishName ?sex ?locatedIn15Name
?dob ?dod ?dom ?bornLocationName ?occupation
where {
?person a hc:Person ;
hc:englishName ?englishName ;
hc:sex ?sex;
hc:subjectID ?subjectID;
optional { ?person hc:livedIn11 ?livedIn11 .
?livedIn11 hc:englishName ?lived11LocationName .
?livedIn11 hc:locatedIn11 ?locatedIn11 .
?locatedIn11 hc:englishName ?locatedIn11Name .
?locatedIn11 hc:locatedIn15 ?locatedIn15 .
?locatedIn15 hc:englishName ?locatedIn15Name .
} .
optional {?person hc:born ?dob } .
optional {?person hc:dateOfDeath ?dod } .
optional {?person hc:dateOfMarriage ?dom } .
optional { ?person hc:bornIn ?bornIn .
?bornIn hc:englishName ?bornLocationName .
?bornIn hc:easting ?easting .
?bornIn hc:northing ?northing } .
optional { ?person hc:occupation ?occupation }
FILTER regex(?englishName, "^FirstName LastName")
}
GROUP BY
?subjectID ?englishName ?sex
?locatedIn15Name ?dob ?dod ?dom
?bornLocationName ?occupation
答案 0 :(得分:12)
重新输入错误消息:
SELECT中的非组键变量:?占用
您可以使用SAMPLE()
聚合来避免这种情况 - 这样您就可以只对?subjectID
进行分组,但仍然可以为其余变量选择值,前提是您只关心为这些变量获取一个值其他变量。
以下是一个简单的例子:
SELECT ?subjectID (SAMPLE(?dob) AS ?dateOfBirth)
WHERE
{
?person a hc:Person ;
hc:subjectID ?subjectID .
OPTIONAL { ?person hc:born ?dob }
}
GROUP BY ?subjectID
答案 1 :(得分:9)
首先要注意的是,在RDF / SPARQL中确实没有密钥。您正在查询图表,?subjectID
可能只是为您选择的其他变量提供了几种可能的值组合。这是由您查询的图形的形状引起的:也许您的人有多个英文名称,或者反过来说:相同的英文名称可以由多个人共享。
SPARQL SELECT查询是一个奇怪的野兽:它查询图形结构,但将结果显示为平面表(从技术上讲,它是一系列变量绑定的序列,但它相同的东西)。出现重复是因为基本上遵循图中的不同路径可以找到变量值的不同组合。
因此,您在结果中获得?subjectID
重复值的事实是不可避免的,因为从RDF图的角度来看,这些是查询的唯一解决方案。您无法在不实际丢失信息的情况下过滤掉结果,因此一般情况下很难为您提供解决方案而又不了解更多关于您想要丢弃的'重复项'的信息:您是否只想要一个可能的英文名称?每个科目,或一个可能的出生日期(即使您的数据可能不止一个)?
但是,以下是一些处理/处理此类结果的提示:
首先,您可以选择在ORDER BY
变量上使用?subjectID
子句。这仍然会为您提供具有?subjectID
相同值的多行,但它们都将按顺序排列,因此您可以更有效地处理结果。
另一个解决方案是将您的查询分成两部分:执行第一个查询 only 选择所有唯一主题(以及可能提前知道的所有其他值,它们将是唯一的主题),然后迭代结果并执行单独的查询以获取您感兴趣的其他值,为每个单独的subjectID值。这个解决方案可能听起来像异端(特别是如果你来自SQL背景),但实际上它可能比在一个巨大的查询中做所有事情更快更容易。
另一个解决方案是RobV建议的解决方案:在特定变量上使用SAMPLE
聚合只选择一个(随机)唯一值。其变体是使用GROUP_CONCAT
聚合,它通过将所有可能的值连接成一个字符串来创建单个值。