Programmeren in SPARQL

Uit Wikibooks
Werk in uitvoering.
Deze pagina bevindt zich nog in de opbouwfase.
De auteur ervan heeft zich voorgenomen de genoemde onderwerpen verder uit te werken.
Indien u wilt bijdragen, doe dat dan gerust.

Links[bewerken]

  • SPARQL-uitleg in het Engels op Wikidata

Queries uitvoeren[bewerken]

Om een SparQL query uit te voeren, kun je de query invoeren in: https://query.wikidata.org/

Zoek naar een bepaalde constante waarde[bewerken]

Zoek alle items die voor eigenschap P850 de waarde 744368 hebben:

SELECT ?item WHERE { ?item wdt:P850 '744368' . }

Zoek naar een bepaalde verwijzing[bewerken]

SELECT ?item WHERE  { ?item wdt:P31 wd:Q4167836 . } LIMIT 10

Door de toevoeging van LIMIT 10 worden de eerste 10 waarden opgehaald, waardoor de query geen time-out krijgt, en snel resultaat laat zien.


Property niet leeg[bewerken]

Als een property ingevuld moet zijn met een willekeurige waarde, dan wordt die willekeurige waarde gespecificeerd met dummy0. Als er meerdere properties zo moeten zijn ingevuld, krijgt de volgende uiteraard dummy1, etc.

select ?item where { ?item wdt:P3061 ?dummy0 . }

Wanneer je de waarde ook wilt zien:

select ?item ?BRIN where { ?item wdt:P3061 ?BRIN . }

Label en omschrijving[bewerken]

Met de service:wikibase:label worden bij een item ook de labels opgehaald, met een serviceParam kan ook de taal worden gespecificeerd.

  select ?item ?itemLabel ?itemDescription
  where {
   ?item wdt:P19 wd:Q5128 .
   {service wikibase:label{bd:serviceParam wikibase:language "nl" . }}
  }

Met bijvoorbeeld language "nl,en" worden de omschrijvingen in het nederlands getoond, maar als die niet bestaat wordt de engelse omschrijving getoond

  select ?item ?itemLabel ?itemDescription
  where {
   ?item wdt:P19 wd:Q5128 .
   {service wikibase:label{bd:serviceParam wikibase:language "nl,en" . }}
  }

Persoon met geboorte- en sterfdatum[bewerken]

Met optional geef je aan dat een waarde niet per se hoeft te bestaan. Zonder optional worden items zonder die waarde niet geselecteerd. In onderstaande query krijg je personen die wel een geboortedatum hebben, met bijbehorende sterfdatum indien die is ingevuld.

 select ?person ?geb ?sterf
 where {
  ?person wdt:P31 wd:Q5 .
  {?person wdt:P569 ?geb} .
  optional {?person wdt:P570 ?sterf} .
 } LIMIT 100

Beroepen van Nederlanders[bewerken]

Met COUNT kan iets worden geteld. Met UNION kunnen twee sets worden samengevoegd (OR). Hier wordt de nationaliteit (P27) van Q29999 (Koninkrijk der Nederlanden) en Q55 (Nederland) samengevoegd. De GROUP BY zorgt dat de beroepen worden gesorteerd zodat ze bij elkaar staan, zodat COUNT ze kan tellen.

 select ?value ?valueLabel ?count {{
   SELECT ?value (COUNT(DISTINCT ?a) AS ?count) WHERE {
       ?a wdt:P31 wd:Q5 .
       {?a wdt:P27 wd:Q55 } UNION { ?a wdt:P27 wd:Q29999 }
       ?a wdt:P106 ?value . 
    } GROUP BY ?value
  } {service wikibase:label{bd:serviceParam wikibase:language "nl" . }}
 } ORDER BY DESC (?count)

Twee landen[bewerken]

Alle items met als land Finland of Zweden:

SELECT ?item 
where {
  ?item wdt:P17 ?country. 
  values ?country { wd:Q33 wd:Q34 } 
}

Filter lege waarden[bewerken]

Soms wil je enkel de lege waarden van een veld laten zien, dit doe je met een FILTER (!bound(?<variabele>))

 SELECT ?bridges ?bridgesLabel ?gemeenteLabel
 WHERE {
       ?bridges wdt:P17 wd:Q55 .
       ?bridges wdt:P31/wdt:P279* wd:Q12280 .
       OPTIONAL {?bridges wdt:P177 ?crosses} .
       OPTIONAL {?bridges wdt:P131 ?gemeente} .
      {service wikibase:label {bd:serviceParam wikibase:language "nl"}}
 FILTER ( !bound(?crosses) ) .
 }

Nederlandse gemeentes met meer dan 25000 inwoners[bewerken]

Met FILTER kun je bepaalde waarden weglaten, in dit geval gemeenten met minder dan 25001 inwoners.

 SELECT ?item ?itemLabel ?inwonertal ?itemDescription ?landLabel
 WHERE {
  ?item wdt:P31 wd:Q2039348 .
  ?item wdt:P17 ?land .
  ?item wdt:P1082 ?inwonertal
  {service wikibase:label {bd:serviceParam wikibase:language "nl"}}   
  FILTER (?inwonertal > 25000)
 }

Omschrijving is "iets"[bewerken]

De omschrijving wordt hier op een alternatieve manier opgehaald, maar zo kan er wel worden gefilterd op een bepaalde waarde, in dit geval "gemeente" zonder de provincienaam. Hopelijk geeft de query nog resultaat, anders kun je filteren op "gemeente in XXX" waarbij XXX een van de Nederlandse provincies is.

SELECT ?item ?itemLabel ?inwonertal ?d ?landLabel 
 WHERE {
  ?item wdt:P31 wd:Q2039348 .
  ?item wdt:P17 ?land .
  ?item wdt:P1082 ?inwonertal .
  
  OPTIONAL { ?item schema:description ?d .  FILTER(lang(?d)="nl") }
  {service wikibase:label {bd:serviceParam wikibase:language "nl"}}   
  FILTER (str(?d)='gemeente')
} ORDER BY DESC(?inwonertal)

Tussen een periode[bewerken]

Deze query laat zien welke vrouwen op nl-wiki staan, die geboren zijn tussen 1850-1920. Dezelfde query voor mannen geeft momenteel een time-out.

select DISTINCT ?item ?itemLabel ?gebjaar ?wikinl where {
  ?item wdt:P31 wd:Q5 .
  ?item wdt:P21 wd:Q6581072 .
  ?item wdt:P569 ?gebjaar .
  ?sitelink schema:about ?item .
  FILTER ( ?gebjaar >= "1850-01-01T00:00:00Z"^^xsd:dateTime && ?gebjaar <= "1920-01-01T00:00:00Z"^^xsd:dateTime )
  FILTER EXISTS {?wikinl schema:about ?item . ?wikinl schema:inLanguage "nl"}   
  {service wikibase:label {bd:serviceParam wikibase:language "nl"}} 
}


Alle tennisspeelsters met een FedCup-ID zonder artikel op nl-wiki[bewerken]

En een extra filter om enkel de items te tonen waarvan de FedCup-ID begint met een "1" of "2". Momenteel worden alle FedCUp-IDs aangepast, dus binnenkort geeft deze query geen resultaat meer, verwijder dan het laatste filter, of filter op alles dat begint met een "8". Het is nu bedoelt ter demonstratie wat er mogelijk is. De DISTINCT zorgt ervoor dat je iedere speelster maar 1x in het overzicht krijgt, anders krijg je ze voor iedere taalversie een keer.

select distinct ?item ?itemLabel ?fedcupID 
where  {?item wdt:P2642 ?fedcupID . 
        ?sitelink schema:about ?item . 
        FILTER NOT EXISTS {?wen schema:about ?item . ?wen schema:inLanguage "nl" } 
        {service wikibase:label {bd:serviceParam wikibase:language "en"}}  
}

Items zonder afbeelding[bewerken]

Met FILTER not exists { ?item wdt:P18 ?image } worden items geselecteerd zonder afbeelding

#monumenten in Zeist zonder afbeelding
SELECT ?item ?gemeenteLabel ?monumentnr ?itemLabel ?itemDescription ?location WHERE {
  ?item wdt:P131 wd:Q10056. # Zeist
  ?item wdt:P1435 wd:Q916333.# Rijksmonument
  OPTIONAL { ?item wdt:P131 ?gemeente }
  ?item wdt:P625 ?location.
  ?item wdt:P359 ?monumentnr.
  FILTER not exists { ?item wdt:P18 ?image }
  SERVICE wikibase:label { bd:serviceParam wikibase:language "nl". }
}
LIMIT 1000

Hoofdsteden van de landen[bewerken]

Onderstaande query toont de items die hoofdstad zijn van een land. Het land wordt opgehaald in de variabele ?country, en aan ?hoofdstad gekoppeld in de regel daarboven.

SELECT ?hoofdstad ?hoofdstadLabel ?hoofdstadDescription WHERE {
    ?hoofdstad wdt:P1376 ?country.
    ?country wdt:P31 wd:Q6256 .
	SERVICE wikibase:label { bd:serviceParam wikibase:language "nl". }
}

Beroepen (zonder vertaling)[bewerken]

select ?item ?itemLabel where 
{?item wdt:P31 wd:Q28640 . 
   SERVICE wikibase:label { bd:serviceParam wikibase:language "nl". }
}
order by ?itemLabel

Stations in de buurt van[bewerken]

Onderstaande query zoekt alle stations die naburig zijn aan Utrecht CS.

select ?naburigstation ?naburigstationLabel
where
{
  VALUES ?UtrechtCS {wd:Q575655}
  ?UtrechtCS wdt:P197 ?naburigstation
  SERVICE wikibase:label { bd:serviceParam wikibase:language "nl". }           
}

Deze query geeft hetzelfde resultaat als deze query:

select ?item ?itemLabel
where
{
  ?item wdt:P197 wd:Q575655
  SERVICE wikibase:label { bd:serviceParam wikibase:language "nl". }           
}

Voedsel zonder ingredienten[bewerken]

select ?item where {
   ?item wdt:P31 wd:Q2095 .
   optional {?item  wdt:P527 ?ingredient }
   filter (!bound(?ingredient))
}

Dit kan ook als volgt, met hetzelfde resultaat:

select ?item where {
   ?item wdt:P31 wd:Q2095 .
   filter not exists {?item  wdt:P527 ?ingredient} 
}

Deelnemers badmintontoernooi zonder geslacht[bewerken]

SELECT ?item ?itemLabel ?participantLabel WHERE {
  {
    SELECT ?item ?itemLabel ?participantLabel (CONTAINS(?participantLabel, "Women's") AS ?is_woman) WHERE {
      ?item wdt:P31 wd:Q5; wdt:P106 wd:Q13141064; wdt:P1344 ?participant .
      MINUS { ?item wdt:P21 [] } .
      SERVICE wikibase:label {bd:serviceParam wikibase:language "en" .} .
    }
  } .
  FILTER( ?is_woman = true ) .
}

Duitsers met een beroep en n/a in de omschrijving[bewerken]

SELECT ?item ?itemDescription WHERE {
  ?item wdt:P27 wd:Q183 .
  ?item wdt:P31 wd:Q5 .
  ?item wdt:P106 ?beroep
  optional {
    ?item schema:description ?itemDescription .
    FILTER(lang(?itemDescription)="nl") } .
    FILTER (REGEX(STR(?itemDescription), "n[/]a", "i"))
}


Beroepen zonder label, gesorteerd op hoe vaak gebruikt[bewerken]

Deze query gaf mij eerst time-outs, maar door deze op de juiste manier te nesten was dit te omzeilen. De binnenste select vind alle beroepen zonder omschrijving, en ieder beroep wordt aan een ?item gekoppeld en vervolgens geteld. Dit wordt omgekeerd gesorteerd gepresenteerd, zodat het beroep zonder omschrijving dat het meest gebruikt wordt bovenaan staan. Omdat ik een script heb dat deze beroepen gebruikt om omschrijvingen bij personen te genereren, was dit een cruciaal script om de missende beroepen te vinden.

SELECT ?beroep (COUNT(?item) AS ?totalitems) WHERE {{
SELECT DISTINCT ?beroep 
   WHERE { 
           ?beroep wdt:P31 wd:Q28640 . 
           OPTIONAL {?beroep rdfs:label ?beroeplabel filter (lang(?beroeplabel) = "nl").  }
           FILTER (!BOUND(?beroeplabel))
         }
   } ?item wdt:P106 ?beroep
} GROUP BY ?beroep
ORDER BY DESC (?totalitems)

Gebruik van een qualifier[bewerken]

Toon alle bruggen met een hoogte in <meters>

SELECT ?item ?itemLabel ?height WHERE {
  ?item wdt:P31/wdt:P279* wd:Q12280;
        p:P2048 ?statement .
  {
    ?statement psv:P2048 [
      wikibase:quantityAmount ?height; wikibase:quantityUnit wd:Q11573
    ] .
  } .
  SERVICE wikibase:label { bd:serviceParam wikibase:language "nl" } .
}

Chinese gemeenten met de Engelse en Nederlandse naam[bewerken]

Zonder de optional worden de lege waarden weggefilterd.

select ?item ?labelen ?labelnl
where {
  ?item wdt:P31 wd:Q735428 .
  OPTIONAL {?item rdfs:label ?labelen filter(lang(?labelen)="en") }
  OPTIONAL {?item rdfs:label ?labelnl filter(lang(?labelnl)="nl") }
 
}

Nederlandse tennisers[bewerken]

Gesorteerd naar aantal statements dat ze ingevuld hebben

SELECT ?item ?statementCount
WHERE {
  ?item wdt:P31 wd:Q5.
  ?item wdt:P27 wd:Q29999.
  ?item wdt:P106 wd:Q10833314.
  ?item wikibase:statements ?statementCount.
} order by (?statementCount)

Items met een bepaalde omschrijving/alias in een bepaalde taal[bewerken]

SELECT * { ?item schema:description "italienesche Foussballspiller"@lb }
SELECT * { ?a skos:altLabel "protein"@en }

Belgische steden die een stedenband hebben[bewerken]

select ?stedenbandLabel ?itemLabel ?landLabel
where {
  ?item wdt:P190 ?stedenband .
  ?item wdt:P17 ?land .
  ?stedenband wdt:P17 wd:Q31 .
   {service wikibase:label {bd:serviceParam wikibase:language "nl"}}
} ORDER BY ?stedenbandLabel

Items met hun property[bewerken]

Waarbij de referentie/source/bron verwijzen naar http://web.archive/org en niet naar https

SELECT DISTINCT ?item ?p 
WHERE { 
  ?item ?p [prov:wasDerivedFrom [pr:P1065 ?reference ]] .  
  filter(strstarts(str(?reference), 'http://web.archive.org')) 
}

isBLANK[bewerken]

Properties kunnen op "geen waarde" worden gezet, deze kunnen weer met isBLANK worden gefilterd/gevonden.

select ?item where {?item wdt:P570 ?died . FILTER isBLANK(?died)}

unknown Value[bewerken]

Properties kunnen ook "onbekende waarde" hebben. Die zijn te vinden met isSomeValue

 select ?item where {?item wdt:P570 ?died . FILTER wikibase:isSomeValue(?died)}

filter[bewerken]

Filteren van items die een property in het geheel niet hebben:

SELECT ?levend ?dob ?died WHERE {
  ?levend wdt:P31 wd:Q5;
    wdt:P106 wd:Q937857;
    wdt:P21 wd:Q6581072;
    optional {?levend wdt:P569 ?dob}      
    filter not exists {?levend wdt:P570       ?died}
}

Preferred rank[bewerken]

Als een eigenschap een preferred rank heeft, wordt deze teruggegeven voor een wdt:Pxx query. Met p:Pxx/ps:Pxx krijg je ze allemaal, ongeacht de rank.

SELECT * WHERE {
  ?i p:P31/ps:P31 wd:Q42744322.
  ?i p:P31/ps:P31 wd:Q13539802.
#  ?i wdt:p31 wd:Q262166.
}

Property with a qualifier[bewerken]

SELECT ?item ?itemLabel ?itemDescription
{
	?item p:P225 / pq:P405 wd:Q927667 . 
	SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}

Unieke identifiers die meer dan een keer voorkomen[bewerken]

#find double SD-id's
select ?value ?count {{
   SELECT ?value (COUNT(DISTINCT ?a) AS ?count) WHERE {
       ?a wdt:P31 wd:Q5 .
       ?a wdt:P4381 ?value . #SoccerDonna-id
    } GROUP BY ?value
  } {service wikibase:label{bd:serviceParam wikibase:language "nl" . }}
  filter (?count>1)                     
 } ORDER BY DESC (?count)

Met iets tussen haakjes[bewerken]

SELECT *
{
  hint:Query hint:optimizer "None".
  SERVICE wikibase:mwapi {
    bd:serviceParam wikibase:endpoint "www.wikidata.org" .
    bd:serviceParam wikibase:api "Generator" .
    bd:serviceParam mwapi:generator "search" .
    bd:serviceParam mwapi:gsrsearch 'inlabel:vries@nl haswbstatement:P31=Q5' .
    bd:serviceParam mwapi:gsrlimit "max" .    
    bd:serviceParam mwapi:gsrnamespace "0" .    
    ?item wikibase:apiOutputItem mwapi:title  .    
  }
  ?item rdfs:label ?l.
  FILTER(REGEX(?l, "\\)$") && lang(?l)="nl").  
}

RANDOM resultaat[bewerken]

De resultaten worden gecached, dus als je de query snel achter elkaar uitvoert, krijg je steeds hetzelfde resultaat, maar na langere/enige tijd krijg je een nieuwe set. Door "iets" aan de query te veranderen (een spatie maakt vaak al een verschil) forceer je een nieuwe resultaatset.

select ?item where {
    select ?item where {?item wdt:P31 wd:Q5 . ?item wdt:P106 ?beroep} LIMIT 3
  } ORDER BY MD5(CONCAT(STR(?item), STR(NOW())))

Belgische vrouwen met veel interwikilinks[bewerken]

SELECT ?subject ?subjectLabel ?statements ?sitelinks ?gebdatum (GROUP_CONCAT(?beroepLabel) AS ?beroepen) 
WHERE
{ ?subject wdt:P31 wd:Q5.
 VALUES ?nationaliteit { wd:Q31 }  # Koninkrijk der Nederlanden, Nederland, Republiek der Zeven Verenigde Nederlanden
 VALUES ?sekse {wd:Q6581072 } # vrouwelijk 
  ?subject wdt:P569 ?gebdatum. 
  ?subject wdt:P106 ?beroep. 
 ?subject wdt:P27 ?nationaliteit. 
  ?subject wdt:P21 ?sekse.
  ?subject wikibase:statements ?statements.
  ?subject wikibase:sitelinks  ?sitelinks.
# FILTER(?sitelinks >= 20 ).
 
  FILTER NOT EXISTS {
    ?nllanguagelink schema:about ?subject.
    ?nllanguagelink schema:inLanguage "nl". 
    ?nllanguagelink schema:isPartOf <https://nl.wikipedia.org/>
  }
  SERVICE wikibase:label { bd:serviceParam wikibase:language "nl,en".
                           ?subject       rdfs:label ?subjectLabel.
                           ?beroep      rdfs:label ?beroepLabel.
                          ?nationaliteit rdfs:label ?nationaliteitLabel.}
}
GROUP BY ?subject ?subjectLabel ?statements ?sitelinks ?gebdatum
ORDER BY DESC(?sitelinks)
LIMIT 500

Meer voorbeelden[bewerken]

Informatie afkomstig van https://nl.wikibooks.org Wikibooks NL.
Wikibooks NL is onderdeel van de wikimediafoundation.