在Sparql查询中优先化属性

时间:2016-04-25 21:46:09

标签: sparql wikidata

这是关于Sparql和Wikidata的问题。 我想制定一个返回实例类型关系的查询,但如果它不可用则返回其子类。我试过了:

SELECT DISTINCT  ?ent_type  WHERE { 

 { wd:Q7696957 wdt:P31 ?instanceof . } UNION 
 { wd:Q7696957 wdt:P31/wdt:P279? ?subclass .  } UNION 
 { wd:Q7696957 wdt:P279* ?subclass  . } 

 BIND ( IF (BOUND (?instanceof), ?instanceof, ?subclass ) as ?ent_type  ) 

但不幸的是,这会返回所有解决方案,而我只想要一个解决方案

ent_type
----------
wd:Q811979
wd:Q386724
wd:Q811430
wd:Q7696957

2 个答案:

答案 0 :(得分:5)

您可以使用coalesce来实现此目标:

select distinct ?ent_type where { 
  optional { wd:Q7696957 wdt:P31 ?direct }
  optional { wd:Q7696957 wdt:P31/wdt:P279? ?indirect }
  optional { wd:Q7696957 wdt:P279* ?ancestor }
  bind(coalesce(?direct, ?indirect, ?ancestor) as ?ent_type)
}

答案 1 :(得分:2)

为了简化约书亚的答案,你实际上并不需要合并:

select distinct ?ent_type where { 
  optional { wd:Q7696957 wdt:P31 ?ent_typee . }
  optional { wd:Q7696957 wdt:P31/wdt:P279? ?ent_type . }
  optional { wd:Q7696957 wdt:P279* ?ent_type . }
}

如果有多个选项具有相同的变量名称(此处为?ent_type),则第一个“成功”选项将绑定变量。

但是,您的查询逻辑似乎存在问题:如果wdt:P31没有值,那么wdt:P31/wdt:P279?也没有,所以永远不会出现中间情况满足了。此外,wdt:P279*将(因为*)将返回资源本身(wd:Q7696957),如果wdt:P279没有值(可能是您想要的,也可能不是) )。