0

I'm trying to load a list of African countries from Wikidata together with their currency. This is my current query:

SELECT DISTINCT ?item $itemLabel ?currency ?currencyLabel ?currencyEndDate
  WHERE {
    ?item wdt:P31 wd:Q3624078.                                # select only sovereign states
    ?item wdt:P706/wdt:P361*|wdt:P361*|wdt:P30 wd:Q15.        # select items which are geographically in Africa

    ?item p:P31 ?statement.
    ?statement ps:P31 wd:Q3624078.
    FILTER NOT EXISTS { ?statement pq:P582 ?end. }            # filter out items which are not sovereign states anymore
    FILTER NOT EXISTS { ?item wdt:P31 wd:Q3024240. }          # filter out historical countries

    OPTIONAL {
      ?item p:P38 ?currencyStatement.
      ?currencyStatement ps:P38 ?currency.
      OPTIONAL {
        ?currencyStatement pq:P582 ?currencyEndDate.
      }
      #FILTER (?currencyEndDate = "")
    }

    SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
  }
  ORDER BY ASC($itemLabel)

You can try it here.

As you can see, some countries have more than one currency, but mostly this is due to a past currency which was eventually replaced. The past currencies have a end date qualifier (P:582), which is loaded into the variable ?currencyEndDate.

Now I'd like to use ?currencyEndDate in the FILTER clause at line 17. But as soon as I activate this line, the currencies are gone from all results.

If I move the FILTER line two lines further down (outside of the OPTIONAL), then I get no results at all.

I'd be grateful for an explanation of

  • how to do it
  • and why my queries don't work as expected.
logi-kal
  • 7,107
  • 6
  • 31
  • 43
Jonas Sourlier
  • 13,684
  • 16
  • 77
  • 148
  • 1
    Are you looking for `FILTER (!bound(?currencyEndDate))`? – cygri May 05 '19 at 21:46
  • 2
    The more intuitive way would be to do `FILTER NOT EXISTS {?currencyStatement pq:P582 ?currencyEndDate. }` instead of the OPTIONAL + FILTER to avoid old currencies. And as cygri said, it has to be `FILTER(!bound(?currencyEndDate))` - your `FILTER` just checks if there is a value which is the empty string. Note, the combination `OPTIONAL {...} FILTER(!bound())` was used in SPARQL 1.0 to query for non existence but with SPARQL 1.1 the `NOT EXISTS` feature was introduced which is more understandable for many people. – UninformedUser May 06 '19 at 04:28
  • Thanks @cygri and AKSW. – Jonas Sourlier May 06 '19 at 08:57

0 Answers0