Cheatsheets:SPARQL: Difference between revisions

From Wikibase
Jump to navigation Jump to search
Fix: running-example table delimiters; keep inline syntaxhighlight mid-line (line-start tags render as block pre) (via update-page on MediaWiki MCP Server)
Fix logical row: wrap && || ! in inline syntaxhighlight so || is not parsed as table cell separator (via update-page on MediaWiki MCP Server)
Tag: Replaced
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)

Revision as of 11:32, 19 August 2026

Languages: English · français · Esperanto

Category Operators / functions
comparison = < > <= >= !=
logical && || !
string STR() CONTAINS() STRSTARTS() REGEX()
numeric ABS() ROUND() FLOOR() CEIL()
date/time YEAR() MONTH() DAY() NOW()
term tests isIRI() isBlank() isLiteral() LANG() DATATYPE()