|
|
| Line 1: |
Line 1: |
| {{Cheatsheet}}
| |
|
| |
| SPARQL 1.1 quick syntax reference — for people who already know what SPARQL is
| |
| and need reminders on syntax. All examples run as-is against the public
| |
| Wikidata endpoint <syntaxhighlight lang="text" inline>https://query.wikidata.org/sparql</syntaxhighlight>.
| |
| For a proper tutorial, take the
| |
| [https://www.wikidata.org/wiki/Wikidata:SPARQL_tutorial Wikidata SPARQL tutorial].
| |
| For querying a different Wikibase instance (endpoint, prefixes, label service),
| |
| see [[Help:Contributing/query]].
| |
|
| |
| == Running example ==
| |
|
| |
| How many dogs and cats are in Wikidata?
| |
|
| |
| <syntaxhighlight lang="sparql">
| |
| # wd: = entity (Q…), wdt: = property value (P…), SERVICE = label lookup
| |
| SELECT ?animal ?animalLabel (COUNT(?item) AS ?count) WHERE {
| |
| VALUES ?animal { wd:Q144 wd:Q146 } # dog, cat
| |
| ?item wdt:P31 ?animal . # ?item is an instance of ?animal
| |
| SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
| |
| }
| |
| GROUP BY ?animal ?animalLabel
| |
| </syntaxhighlight>
| |
|
| |
| {| class="wikitable"
| |
| ! Animal !! Count
| |
| |-
| |
| | dog || 553
| |
| |-
| |
| | cat || 239
| |
| |}
| |
|
| |
| == Query forms ==
| |
|
| |
| {| class="wikitable"
| |
| ! Form !! Returns !! Use when
| |
| |-
| |
| | SELECT || table of variable bindings || you want rows of data (the rest of this sheet)
| |
| |-
| |
| | ASK || true/false || you only need to know whether something exists
| |
| |-
| |
| | CONSTRUCT || an RDF graph (triples) || you want the result as RDF, not a table
| |
| |-
| |
| | DESCRIBE || a graph describing the resource || you want everything known about an entity
| |
| |}
| |
|
| |
| <syntaxhighlight lang="sparql">
| |
| # Is there at least one dog in Wikidata?
| |
| ASK WHERE { ?x wdt:P31 wd:Q144 . } # → true
| |
|
| |
| # Every dog as an RDF graph (first two)
| |
| CONSTRUCT { ?x wdt:P31 wd:Q144 . }
| |
| WHERE { ?x wdt:P31 wd:Q144 . } LIMIT 2
| |
| </syntaxhighlight>
| |
|
| |
| == Triple patterns & literals ==
| |
|
| |
| A triple pattern is <syntaxhighlight lang="sparql" inline>subject predicate object .</syntaxhighlight> —
| |
| each part may be a variable, an IRI, or a literal.
| |
|
| |
| <syntaxhighlight lang="sparql">
| |
| # What is the population of France? (→ 68,605,616)
| |
| SELECT ?population WHERE {
| |
| wd:Q142 wdt:P1082 ?population .
| |
| }
| |
|
| |
| # Literals can carry datatypes or language tags:
| |
| # "42"^^xsd:integer "2026-08-19"^^xsd:date
| |
| # "dog"@en "chien"@fr
| |
| # A blank node means "some unnamed thing":
| |
| # wd:Q144 wdt:depicted-by [] . # dog depicted by something
| |
| </syntaxhighlight>
| |
|
| |
| == Solution modifiers ==
| |
|
| |
| {| class="wikitable"
| |
| ! Clause !! What it does
| |
| |-
| |
| | DISTINCT || drop duplicate rows
| |
| |-
| |
| | ORDER BY || sort (ASC(?) / DESC(?))
| |
| |-
| |
| | LIMIT n || at most n rows
| |
| |-
| |
| | OFFSET n || skip n rows (paging)
| |
| |-
| |
| | GROUP BY || group rows for aggregation (see Aggregates)
| |
| |}
| |
|
| |
| <syntaxhighlight lang="sparql">
| |
| # The 3 most populous countries (ORDER BY + LIMIT)
| |
| SELECT ?countryLabel ?population WHERE {
| |
| ?country wdt:P31 wd:Q6256 . # instance of: sovereign state
| |
| ?country wdt:P1082 ?population .
| |
| SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
| |
| }
| |
| ORDER BY DESC(?population)
| |
| LIMIT 3
| |
| </syntaxhighlight>
| |
|
| |
| Result: China 1,404,890,000 · India 1,326,093,247 · United States 340,110,988
| |
|
| |
| == FILTER ==
| |
|
| |
| {| class="wikitable" | | {| class="wikitable" |
| ! Category !! Operators / functions | | ! Category !! Operators / functions |
| Line 108: |
Line 4: |
| | comparison || = < > <= >= != | | | comparison || = < > <= >= != |
| |- | | |- |
| | logical || && || ! | | | logical || <syntaxhighlight lang="sparql" inline>&& || !</syntaxhighlight> |
| |- | | |- |
| | string || STR() CONTAINS() STRSTARTS() REGEX() | | | string || STR() CONTAINS() STRSTARTS() REGEX() |
| Line 118: |
Line 14: |
| | term tests || isIRI() isBlank() isLiteral() LANG() DATATYPE() | | | term tests || isIRI() isBlank() isLiteral() LANG() DATATYPE() |
| |} | | |} |
|
| |
| <syntaxhighlight lang="sparql">
| |
| # Countries with more than 1 billion people (→ China, India)
| |
| SELECT ?countryLabel ?population WHERE {
| |
| ?country wdt:P31 wd:Q6256 .
| |
| ?country wdt:P1082 ?population .
| |
| FILTER(?population > 1000000000)
| |
| SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
| |
| }
| |
|
| |
| # France's population in millions (FILTER + BIND arithmetic)
| |
| SELECT ?population ?millions WHERE {
| |
| wd:Q142 wdt:P1082 ?population .
| |
| BIND(?population / 1000000 AS ?millions)
| |
| } # → 68.605616
| |
| </syntaxhighlight>
| |
|
| |
| == VALUES & BIND ==
| |
|
| |
| <syntaxhighlight lang="sparql">
| |
| # Restrict ?animal to a fixed list (see the running example)
| |
| VALUES ?animal { wd:Q144 wd:Q146 }
| |
|
| |
| # Compute a new variable from existing ones
| |
| BIND(?population / 1000000 AS ?millions)
| |
| </syntaxhighlight>
| |
|
| |
| == OPTIONAL, UNION, MINUS ==
| |
|
| |
| {| class="wikitable"
| |
| ! Keyword !! Meaning
| |
| |-
| |
| | OPTIONAL || left join: keep the row, leave the variable unbound when absent
| |
| |-
| |
| | UNION || alternatives (the default between patterns is AND, not OR)
| |
| |-
| |
| | MINUS || remove rows that match the pattern
| |
| |}
| |
|
| |
| <syntaxhighlight lang="sparql">
| |
| # Einstein (died 1955) vs Obama (alive): OPTIONAL leaves ?deathLabel unbound
| |
| SELECT ?personLabel ?deathLabel WHERE {
| |
| VALUES ?person { wd:Q937 wd:Q76 } # Einstein, Barack Obama
| |
| OPTIONAL { ?person wdt:P570 ?death . }
| |
| SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
| |
| }
| |
| # → Albert Einstein 1955-04-18
| |
| # → Barack Obama (no death row)
| |
|
| |
| # Nobel laureates minus the French ones (MINUS)
| |
| SELECT ?personLabel WHERE {
| |
| ?person wdt:P166 wd:Q7191 .
| |
| MINUS { ?person wdt:P27 wd:Q142 . }
| |
| SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
| |
| }
| |
| LIMIT 3
| |
|
| |
| # Dogs AND cats in one result set (UNION + DISTINCT + GROUP BY)
| |
| SELECT ?animalLabel (COUNT(?item) AS ?n) WHERE {
| |
| { ?item wdt:P31 wd:Q144 . BIND("dog" AS ?animalLabel) }
| |
| UNION
| |
| { ?item wdt:P31 wd:Q146 . BIND("cat" AS ?animalLabel) }
| |
| }
| |
| GROUP BY ?animalLabel
| |
| </syntaxhighlight>
| |
|
| |
| == Property paths ==
| |
|
| |
| {| class="wikitable"
| |
| ! Path !! Meaning
| |
| |-
| |
| | wdt:P40/wdt:P40 || two hops (sequence)
| |
| |-
| |
| | wdt:P40+ || one or more hops
| |
| |-
| |
| | wdt:P40* || zero or more hops
| |
| |-
| |
| | wdt:P40? || zero or one hop
| |
| |-
| |
| | wdt:P40|wdt:P41 || either property
| |
| |-
| |
| | ^wdt:P40 || inverse direction
| |
| |-
| |
| | !wdt:P40 || any property except P40
| |
| |}
| |
|
| |
| <syntaxhighlight lang="sparql">
| |
| # Named dogs, including breeds and other subclasses of dog
| |
| # (wdt:P31/wdt:P279* = "instance of something that is a dog or a subclass of dog")
| |
| SELECT ?thing ?thingLabel WHERE {
| |
| ?thing wdt:P31/wdt:P279* wd:Q144 .
| |
| SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
| |
| }
| |
| LIMIT 3
| |
| </syntaxhighlight>
| |
|
| |
| Result: Theo · Tich · Tickle Em Jock
| |
|
| |
| == Aggregates ==
| |
|
| |
| COUNT, SUM, AVG, MIN, MAX, SAMPLE (pick one arbitrary value), GROUP_CONCAT.
| |
|
| |
| <syntaxhighlight lang="sparql">
| |
| # Species with more than 400 direct instances (the running example with HAVING)
| |
| SELECT ?animalLabel (COUNT(?item) AS ?n) WHERE {
| |
| VALUES ?animal { wd:Q144 wd:Q146 }
| |
| ?item wdt:P31 ?animal .
| |
| SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
| |
| }
| |
| GROUP BY ?animal ?animalLabel
| |
| HAVING (COUNT(?item) > 400) # → only dog: 553
| |
|
| |
| # Collect labels into one cell
| |
| SELECT ?personLabel (GROUP_CONCAT(?awardLabel; SEPARATOR=", ") AS ?awards) WHERE {
| |
| VALUES ?person { wd:Q937 }
| |
| ?person wdt:P166 ?award .
| |
| SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
| |
| }
| |
| GROUP BY ?personLabel
| |
| </syntaxhighlight>
| |
|
| |
| == Subqueries ==
| |
|
| |
| A query inside a query — useful for "the X with the max Y" patterns.
| |
|
| |
| <syntaxhighlight lang="sparql">
| |
| # The most populous country, computed via a subquery (→ China)
| |
| SELECT ?countryLabel ?max WHERE {
| |
| {
| |
| SELECT (MAX(?population) AS ?max) WHERE {
| |
| ?c wdt:P31 wd:Q6256 .
| |
| ?c wdt:P1082 ?population .
| |
| }
| |
| }
| |
| ?country wdt:P31 wd:Q6256 .
| |
| ?country wdt:P1082 ?max .
| |
| SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
| |
| }
| |
| </syntaxhighlight>
| |
|
| |
| == SERVICE (labels, federation) ==
| |
|
| |
| The label service turns entity IDs into human-readable labels — used in most
| |
| queries above:
| |
|
| |
| <syntaxhighlight lang="sparql">
| |
| SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
| |
| # then reference ?xLabel for every ?x in the query
| |
| </syntaxhighlight>
| |
|
| |
| <syntaxhighlight lang="sparql">
| |
| # Federating to another endpoint (needs the remote's own IRIs, e.g. via owl:sameAs)
| |
| SELECT ?cityLabel WHERE {
| |
| wd:Q64 wdt:P36 ?city .
| |
| ?city owl:sameAs ?dbpediaCity .
| |
| SERVICE <https://dbpedia.org/sparql> {
| |
| ?dbpediaCity rdfs:label ?cityLabel .
| |
| FILTER(LANG(?cityLabel) = "en")
| |
| }
| |
| }
| |
| </syntaxhighlight>
| |
|
| |
| == Common tasks ==
| |
|
| |
| * '''Count rows''': <syntaxhighlight lang="sparql" inline>SELECT (COUNT(*) AS ?n) WHERE { … }</syntaxhighlight>
| |
| * '''Check existence''': <syntaxhighlight lang="sparql" inline>ASK WHERE { … }</syntaxhighlight>
| |
| * '''Deduplicate''': add <syntaxhighlight lang="sparql" inline>DISTINCT</syntaxhighlight>
| |
| * '''Reverse a relation''': <syntaxhighlight lang="sparql" inline>?child ^wdt:P40 ?parent</syntaxhighlight>
| |
| * '''Page through results''': <syntaxhighlight lang="sparql" inline>LIMIT 100 OFFSET 100</syntaxhighlight>
| |
| * '''JSON output''': append <syntaxhighlight lang="text" inline>&format=json</syntaxhighlight> to the endpoint URL
| |
|
| |
| == Gotchas ==
| |
|
| |
| * The default between triple patterns is '''AND (join)''' — use UNION for alternatives.
| |
| * An unbound variable in <syntaxhighlight lang="sparql" inline>FILTER</syntaxhighlight> makes the row fail (unbound ≠ false) — guard with <syntaxhighlight lang="sparql" inline>BOUND()</syntaxhighlight> or restructure with OPTIONAL.
| |
| * Variables used only inside a property path (e.g. <syntaxhighlight lang="sparql" inline>?s wdt:P40/wdt:P40 ?o</syntaxhighlight>) cannot be selected.
| |
| * Blank-node labels (<syntaxhighlight lang="sparql" inline>_:x</syntaxhighlight>) are local to one query — they are not IRIs.
| |
| * Aggregates need GROUP BY for every non-aggregated variable; forgetting one mixes unrelated rows.
| |
| * <syntaxhighlight lang="sparql" inline>FILTER NOT EXISTS</syntaxhighlight> differs from <syntaxhighlight lang="sparql" inline>MINUS</syntaxhighlight> when variables are unbound — prefer MINUS for set-difference semantics.
| |
| * Endpoint prefixes are not universal — <syntaxhighlight lang="sparql" inline>wd:</syntaxhighlight>/<syntaxhighlight lang="sparql" inline>wdt:</syntaxhighlight> are Wikidata's; other instances define their own (see [[Help:Contributing/query]]).
| |
|
| |
| == Further reading ==
| |
|
| |
| * [https://www.wikidata.org/wiki/Wikidata:SPARQL_tutorial Wikidata SPARQL tutorial] — the recommended tutorial
| |
| * [https://www.w3.org/TR/sparql11-query/ SPARQL 1.1 Query Language] — official spec
| |
| * [https://query.wikidata.org/ Wikidata Query Service] — the example endpoint used here
| |
| * [[Help:Contributing/query]] — querying a different instance (endpoint, prefixes, label service)
| |