0

I'm trying to load all sovereign states together with some states with partially recognized sovereignty (Taiwan, Kosovo) in Wikidata's SPARQL endpoint query.wikidata.org. This is my SPARQL:

SELECT ?item ?iso2
WHERE {
 {
    ?item wdt:P31 wd:Q3624078.
    ?item p:P31 ?statement.
    ?statement ps:P31 wd:Q3624078.
    FILTER NOT EXISTS { ?statement pq:P582 ?end. }
  }
  UNION {
    FILTER(?item IN (wd:Q865, wd:Q1246))
  }
  OPTIONAL { ?item wdt:P297 ?iso2. }
}

As you can see, the sovereign states are loaded with SPARQL statements, but Taiwan and Kosovo are added explicitly, using a FILTER clause.

The filter clause itself works fine:

SELECT ?item ?iso2
WHERE {
  FILTER(?item IN (wd:Q865, wd:Q1246))
  OPTIONAL { ?item wdt:P297 ?iso2. }
}

However, the combined statement does not yield the two explicit results wd:865, wd:1246.

What am I doing wrong?

logi-kal
  • 7,107
  • 6
  • 31
  • 43
Jonas Sourlier
  • 13,684
  • 16
  • 77
  • 148
  • 1
    I guess you're misusing FILTER here. The scope of the filter is just inside the UNION part, thus, it does nothing. Why did you put it into a separate UNION clause, I don't get the idea behind this? – UninformedUser Apr 22 '20 at 08:28
  • 1
    Also, not sure what you're trying to achieve, but the more intended SPARQL way would be to use inline data via `VALUES` clause: `SELECT ?item ?iso2 WHERE { VALUES ?item { wd:Q865 wd:Q1246 } ?item wdt:P31 wd:Q3624078. ?item p:P31 ?statement. ?statement ps:P31 wd:Q3624078. FILTER NOT EXISTS { ?statement pq:P582 ?end. } OPTIONAL { ?item wdt:P297 ?iso2. } }` – UninformedUser Apr 22 '20 at 08:29
  • 1
    @UninformedUser Thanks, now I see my error. Your `VALUE` clause is exactly what I needed: `{ VALUES ?item { wd:Q865 wd:Q1246 } } UNION { ?item wdt:P31 wd:Q3624078. ?item p:P31 ?statement. ?statement ps:P31 wd:Q3624078. FILTER NOT EXISTS { ?statement pq:P582 ?end. } }` – Jonas Sourlier Apr 22 '20 at 08:55
  • @UninformedUser if you care about the reputation, write an answer, I'm gonna accept and upvote it. – Jonas Sourlier Apr 22 '20 at 08:56
  • 1
    ah, now I understand why you did you use the `UNION`, you always want to have those two items + additional ones matching a graph pattern. Nah, feel free you answer your own question, cheers – UninformedUser Apr 22 '20 at 09:17

1 Answers1

0

As per user @UninformedUser's comment, the answer is that FILTER always filters out items. It cannot be used to add items to a result set (which seems logical given the terminology). So in my UNION clause, the second result set was always empty.

The right choice to get a result set, whose members are defined explicitly, would be VALUES:

SELECT ?item ?iso2
WHERE {
 {
    ?item wdt:P31 wd:Q3624078.
    ?item p:P31 ?statement.
    ?statement ps:P31 wd:Q3624078.
    FILTER NOT EXISTS { ?statement pq:P582 ?end. }
  }
  UNION {
    VALUES ?item { wd:Q865 wd:Q1246 }
  }
  OPTIONAL { ?item wdt:P297 ?iso2. }
}
Jonas Sourlier
  • 13,684
  • 16
  • 77
  • 148