Nav*_*ava 7 semantic-web sparql
我有一个返回重复项的sparql查询,我希望它只在其中一个值(subjectID)上清理它们.与DISTINCT不同,DISTINCT似乎为所选值的组合找到了唯一值,而不是仅针对其中一个参数.我看到有人在这里建议分组,但是如果我在分组后列出所有参数(我的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
Run Code Online (Sandbox Code Playgroud)
Rob*_*obV 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
Run Code Online (Sandbox Code Playgroud)
首先要注意的是,在RDF/SPARQL中确实没有密钥.您正在查询图形,并且?subjectID可能只是为您选择的其他变量设置了几种可能的值组合.这是由您查询的图形的形状引起的:也许您的人有多个英文名称,或者实际上相反:同一个英文名称可以由多个人共享.
SPARQL SELECT查询是一个奇怪的野兽:它查询图形结构,但将结果显示为一个平面表(从技术上讲,它是一系列变量绑定,但它相同的东西).出现重复是因为基本上遵循图中的不同路径可以找到变量值的不同组合.
因此,您?subjectID在结果中获得重复值的事实是不可避免的,因为从RDF图的角度来看,这些是查询的唯一解决方案.你不能在没有实际丢失信息的情况下过滤掉结果,所以一般来说很难给你一个解决方案而又不知道你想要丢弃哪些 '重复':你只想为每个主题提供一个可能的英文名称,或者一个可能的出生日期(即使您的数据可能不止一个)?
但是,以下是一些处理/处理此类结果的提示:
首先,您可以选择ORDER BY在?subjectID变量上使用一个子句.这仍然会为您提供具有相同值的多行?subjectID,但它们都将按顺序排列,因此您可以更有效地处理结果.
另一种解决方案是将您的查询分成两部分:执行第一个查询,该查询仅选择所有唯一主题(以及可能提前知道的所有其他值,它们在给定主题时将是唯一的),然后迭代结果和为每个单独的subjectID值执行单独的查询以获取您感兴趣的其他值.这个解决方案可能听起来像异端(特别是如果你来自SQL背景),但实际上它可能比在一个巨大的查询中做所有事情更快更容易.
另一个解决方案是RobV建议的解决方案:使用SAMPLE特定变量上的聚合来选择一个(随机)唯一值.对此的一种变体是使用GROUP_CONCAT聚合,通过将所有可能的值连接成单个字符串来创建单个值.