Reputation: 127
This is a question about Sparql and Wikidata. I want to formulate a query that returns an instance-type relation, but if it's not available return its sub-class. I tried:
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 )
But unfortunately this returns all solutions, whereas I only want one solution
ent_type
----------
wd:Q811979
wd:Q386724
wd:Q811430
wd:Q7696957
Upvotes: 2
Views: 143
Reputation: 2277
To simplify Joshua's answer, you don't actually need the coalesce:
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 . }
}
If there are multiple optionals with the same variable name (here ?ent_type
), the first "successful" one will bind the variable.
However, there seems to be a problem with your query logic: if there is no value for wdt:P31
, then neither is there for wdt:P31/wdt:P279?
, so there will never be a situation where the middle condition is met. Also, wdt:P279*
will (because of the *
) return the resource itself (wd:Q7696957
) if there is no value for wdt:P279
(which may or may not be what you want).
Upvotes: 2
Reputation: 85823
You can use coalesce to achieve this:
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)
}
Upvotes: 5