Wikidata:SPARQL query service/Federated queries

The SPARQL service can also include data retrieved from a limited number of external sources.

For example, the following query tries to find a value for TOID (P3120) from the UK Ordnance Survey for items that have a GSS code (2011) (P836) but no TOID (P3120):

SELECT ?item ?itemLabel ?gss ?os_toid WHERE {
  	?item p:P836 ?gss_stmt .
    ?gss_stmt ps:P836 ?gss .
    FILTER NOT EXISTS { ?gss_stmt pq:P582 [] } .
    FILTER NOT EXISTS { ?item wdt:P3120 [] } .
  
    SERVICE <http://data.ordnancesurvey.co.uk/datasets/os-linked-data/apis/sparql> {
      ?os_toid <http://data.ordnancesurvey.co.uk/ontology/admingeo/gssCode> ?gss
    }
    SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Try it!

This is achieved by the section

SERVICE <http://data.ordnancesurvey.co.uk/datasets/os-linked-data/apis/sparql> { 
    ... 
}

which tells WDQS to submit a query to the SPARQL service ("endpoint") provided by the Ordnance Survey at the above URL.

The OS SPARQL service uses the same SPARQL query language as WDQS, but the triples in its database have a different vocabulary of subjects, predicates and objects -- described on its website, and/or on pages for particular items.

Of relevance for this query, the OS database contains triples connecting OS TOIDs and GSS values of the form

?os_toid <http://data.ordnancesurvey.co.uk/ontology/admingeo/gssCode> ?gss

These are retrieved by the federated query above, and joined with the list of items with GSS values that have no existing TOIDs.

(Aside: This query has been used to fill in TOID values that were previously missing, so may now return few or no results. In general, however, care should be taken before adding information from such databases to Wikidata. While it is probably okay to add identifiers to enable linking to items in the external databases, in many cases the federated databases are not licensed CC0, so content from them may not be copied wholesale into Wikidata -- federated query results are allowed, however, so long as the licensing terms of the external databases are acknowledged.)

Japan Search edit

Works in Japan Search by British sculptors edit

PREFIX jps: <https://jpsearch.go.jp/term/property#>
SELECT DISTINCT ?name ?work_link ?work ?creatorLabel ?date
WITH {
  SELECT ?creator WHERE {
     VALUES ?citizenship {wd:Q145 wd:Q174193} . # UK, Britain & Ireland
    ?creator wdt:P6698 [];   # Only get things with a Japan Search ID
   wdt:P27 ?citizenship; wdt:P106 wd:Q1281618}    # sculptors
     } AS %creators
WHERE {
include %creators
  SERVICE <https://jpsearch.go.jp/rdf/sparql/> {
   ?jps_creator owl:sameAs ?creator . # convert Wikidata ID to Japan Search ID
    ?work schema:creator ?jps_creator .  # Works by this artist
    OPTIONAL {?work schema:name ?name }   # This will return separate names in English and Japanese names
    OPTIONAL {?work schema:dateCreated ?date}
    }
FILTER (lang(?name)="en")  # Show only the English name
BIND(URI( REPLACE(STR(?work), "/data/", "/item/") ) AS ?work_link)
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
} ORDER BY ?date
Try it!

Works by Hiroshige known to Wikidata UNION those known to Japan Search edit

PREFIX jps: <https://jpsearch.go.jp/term/property#>
SELECT ?name ?work ?date ?url ?image WHERE {
  {
  SERVICE <https://jpsearch.go.jp/rdf/sparql/> {
    ?jps_creator owl:sameAs wd:Q200798 .
    ?work schema:creator ?jps_creator .
    OPTIONAL {?work schema:dateCreated ?date}
    OPTIONAL {?work schema:image ?image}
    OPTIONAL {?work schema:name ?name}
    FILTER (lang(?name)="ja").  # Show only the Japanese name
    }
BIND(URI( REPLACE(STR(?work), "/data/", "/item/") ) AS ?url)
    }
UNION {
  ?work wdt:P170 wd:Q200798.
  OPTIONAL {?work wdt:P973 ?url}
  OPTIONAL {?work wdt:P18 ?image}
  OPTIONAL {?work wdt:P571 ?date}
  ?work rdfs:label ?name FILTER (lang(?name)="ja")
  }
}
Try it!

UK Parliament edit

UK Parliament constituencies whose official point location is more than 10km from the location in Wikidata edit

# compare lat/long of Parliament and Wikidata constituency records

#defaultView:Map{"hide":["?line"]}
PREFIX parliament:<https://id.parliament.uk/schema/>

SELECT DISTINCT ?constituency ?parlcoord ?item ?itemLabel ?wdcoord ?dist ?line WHERE {
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
  SERVICE <https://api.parliament.uk/sparql> 
    { ?constituency parliament:constituencyGroupHasConstituencyArea ?area .
      ?area parliament:latitude ?lat . ?area parliament:longitude ?long . 
      bind(SUBSTR(str(?constituency),26) as ?parlid) . }
  BIND(concat("Point(",str(?long)," ",str(?lat),")") as ?parlcoord) 
  # get constituencies from Parliament with coordinates
  ?item wdt:P6213 ?parlid . ?item wdt:P31 wd:Q27971968 . ?item wdt:P625 ?wdcoord . 
  # now get them from Wikidata with coordinates
  BIND(geof:distance(?parlcoord, ?wdcoord) as ?dist) . filter (?dist >= 10)
  # now find out the distance (in kms)
  ?item p:P625 ?statementnode. ?statementnode psv:P625 ?valuenode.
  ?valuenode wikibase:geoLatitude ?wikilat . ?valuenode wikibase:geoLongitude ?wikilon.
  BIND(CONCAT('LINESTRING (', STR(?wikilon), ' ', STR(?wikilat), ',', STR(?long), ' ', STR(?lat), ')') AS ?str) .
  BIND(STRDT(?str, geo:wktLiteral) AS ?line) 
}
Try it!