Cheatsheets:SPARQL
Quick reference for smart people — part of our dev cheatsheets collection.
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 https://query.wikidata.org/sparql.
For a proper tutorial, take the
Wikidata SPARQL tutorial.
For querying a different Wikibase instance (endpoint, prefixes, label service),
see Help:Contributing/query.
Running example: dogs and cats
GROUP BY + COUNT + VALUES — how many of each animal are in Wikidata?
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
Result:
dog 553
cat 239
This sheet uses that query as its running example: VALUES and GROUP BY in the
first line, the animal classes (wd:Q144 dog, wd:Q146 cat) as VALUES, the
pattern ?item wdt:P31 ?animal
("is an instance of") as the triple, and COUNT as the aggregate.
Building a query
A query is a list of triple patterns:
subject predicate object .
You know some parts, query the rest:
| Question | Known parts | Pattern |
|---|---|---|
| "What is the population of France?" | subject France (wd:Q142) + predicate population (wdt:P1082) | wd:Q142 wdt:P1082 ?population .
|
| "Which things are dogs?" | predicate instance-of (wdt:P31) + object dog (wd:Q144) | ?x wdt:P31 wd:Q144 .
|
| "What is known about Einstein?" | subject Einstein (wd:Q937) | wd:Q937 ?predicate ?value .
|
Write the question in that order and the query writes itself:
# "What is the population of France?"
SELECT ?population WHERE {
wd:Q142 wdt:P1082 ?population .
}
Result:
68605616
The three kinds of values a triple can hold, each shown in a query:
IRI — a resource: an entity (wd:Q142), a property (wdt:P1082), or anything else. In the pattern above, France and its population property are IRIs; the thing we don't know yet is a variable:
SELECT ?population WHERE {
wd:Q142 wdt:P1082 ?population . # IRI IRI variable
}
Literal — a value, not a resource: a typed number/date, or a string with
a language tag. Dog's English label is the literal "dog"@en:
SELECT ?label WHERE {
wd:Q144 rdfs:label ?label .
FILTER(LANG(?label) = "en")
}
Result:
dog
Other literals: "42"^^xsd:integer,
"2026-08-19"^^xsd:date,
"chien"@fr.
Blank node — "some unnamed thing", written [] or
_:x
. Use it when a value exists but you don't care
what it is — here, dogs that have an image:
SELECT ?dogLabel WHERE {
?dog wdt:P31/wdt:P279* wd:Q144 .
?dog wdt:P18 [] . # has an image — any image will do
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
LIMIT 3
Result:
Diamond
Dog of Osu
Endal
Gotcha: blank-node labels (
_:x) are local to one query — they are not IRIs and cannot be referenced across queries.
Gotcha: the prefixes
wd:/wdt:are Wikidata's; other instances define their own (see Help:Contributing/query).
Query forms
| Form | Returns | Use when |
|---|---|---|
| SELECT | table of variable bindings | you want rows of data |
| 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 |
SELECT — what is the population of France?
SELECT ?population WHERE {
wd:Q142 wdt:P1082 ?population .
}
Result:
68605616
ASK — is there at least one dog in Wikidata?
ASK WHERE { ?x wdt:P31 wd:Q144 . }
Result:
true
CONSTRUCT — every dog as RDF (first two). Each result row becomes a
triple ?x wdt:P31 wd:Q144:
CONSTRUCT { ?x wdt:P31 wd:Q144 . }
WHERE { ?x wdt:P31 wd:Q144 . } LIMIT 2
Result (visualised, N-Triples style):
Q186486 wdt:P31 wd:Q144
Q280571 wdt:P31 wd:Q144
DESCRIBE — everything known about Einstein (all triples with wd:Q937 as subject or object):
DESCRIBE wd:Q937
Result (visualised, N-Triples style, first few of thousands):
Q937 rdfs:label "Albert Einstein"@en
Q937 wdt:P569 1879-03-14
Q937 wdt:P570 1955-04-18
Q937 wdt:P21 wd:Q6581097 # male
Solution modifiers
Each modifier shown without / with, side by side; the highlighted line(s) show what the modifier adds.
DISTINCT — drop duplicate rows. Einstein and Obama are both male, so the gender repeats:
| Without | With DISTINCT |
|---|---|
SELECT ?genderLabel WHERE {
VALUES ?person { wd:Q937 wd:Q76 }
?person wdt:P21 ?gender .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Result: male
male
|
SELECT DISTINCT ?genderLabel WHERE {
VALUES ?person { wd:Q937 wd:Q76 }
?person wdt:P21 ?gender .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Result: male
|
ORDER BY + LIMIT — the 3 most populous countries, sorted descending:
| Without (arbitrary order) | With ORDER BY DESC + LIMIT |
|---|---|
SELECT ?countryLabel ?population WHERE {
VALUES ?country { wd:Q148 wd:Q30 wd:Q668 } # China, US, India
?country wdt:P1082 ?population .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Result: United States 340110988
China 1404890000
India 1326093247
|
SELECT ?countryLabel ?population WHERE {
VALUES ?country { wd:Q148 wd:Q30 wd:Q668 }
?country wdt:P1082 ?population .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY DESC(?population)
Result: China 1404890000
India 1326093247
United States 340110988
|
LIMIT — at most n rows:
| Without (all 3) | With LIMIT 2 |
|---|---|
SELECT ?countryLabel WHERE {
VALUES ?country { wd:Q148 wd:Q30 wd:Q668 }
?country wdt:P1082 ?population .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Result: United States
China
India
|
SELECT ?countryLabel WHERE {
VALUES ?country { wd:Q148 wd:Q30 wd:Q668 }
?country wdt:P1082 ?population .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
LIMIT 2
Result: United States
China
|
OFFSET — skip rows (paging). The 2nd most populous country:
| With LIMIT 1 (first) | With LIMIT 1 OFFSET 1 (second) |
|---|---|
SELECT ?countryLabel ?population WHERE {
?country wdt:P31 wd:Q6256 .
?country wdt:P1082 ?population .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY DESC(?population)
LIMIT 1
Result: China 1404890000
|
SELECT ?countryLabel ?population WHERE {
?country wdt:P31 wd:Q6256 .
?country wdt:P1082 ?population .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY DESC(?population)
LIMIT 1 OFFSET 1
Result: India 1326093247
|
GROUP BY — covered with aggregation (see Aggregates).
FILTER
| Category | Operators / functions |
|---|---|
| comparison | = < > <= >= != |
| logical | && || !
|
| string | STR() CONTAINS() STRSTARTS() STRENDS() REGEX() |
| numeric | ABS() ROUND() FLOOR() CEIL() |
| date/time | YEAR() MONTH() DAY() NOW() |
| term tests | isIRI() isBlank() isLiteral() LANG() DATATYPE() |
comparison — countries with more than 1 billion people:
SELECT ?countryLabel ?population WHERE {
?country wdt:P31 wd:Q6256 .
?country wdt:P1082 ?population .
FILTER(?population > 1000000000)
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Result:
China 1404890000
India 1326093247
logical (AND) — countries with 300M–500M people:
SELECT ?countryLabel ?population WHERE {
?country wdt:P31 wd:Q6256 .
?country wdt:P1082 ?population .
FILTER(?population > 300000000 && ?population < 500000000)
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Result:
United States 340110988
string (STRSTARTS) — countries whose English label starts with "S":
SELECT ?countryLabel WHERE {
?country wdt:P31 wd:Q6256 .
?country rdfs:label ?countryLabel .
FILTER(LANG(?countryLabel) = "en" && STRSTARTS(?countryLabel, "S"))
}
LIMIT 3
Result:
Saint Kitts and Nevis
Somaliland
Saint Vincent and the Grenadines
numeric (ROUND) — France's population in millions, rounded:
SELECT ?millions (ROUND(?millions) AS ?rounded) WHERE {
wd:Q142 wdt:P1082 ?population .
BIND(?population / 1000000 AS ?millions)
}
Result:
68.605616 69
date/time (YEAR) — Einstein's birth year:
SELECT ?personLabel (YEAR(?birth) AS ?year) WHERE {
wd:Q937 wdt:P569 ?birth .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Result:
Albert Einstein 1879
term test (isIRI) — the values of wdt:P31 on a dog
are entities (IRIs), not literals:
SELECT ?o WHERE {
wd:Q144 wdt:P31 ?o .
FILTER(isIRI(?o))
}
Result:
http://www.wikidata.org/entity/Q55983715
http://www.wikidata.org/entity/Q136772238
Gotcha: an unbound variable in a FILTER makes the row fail (unbound ≠ false) — guard with
BOUND()or restructure with OPTIONAL.
VALUES & BIND
VALUES restricts a variable to a list; BIND computes a new variable. Together: birth years of two people, computed, not looked up:
SELECT ?personLabel ?birthYear WHERE {
VALUES ?person { wd:Q937 wd:Q76 } # Einstein, Obama
?person wdt:P569 ?birth .
BIND(YEAR(?birth) AS ?birthYear)
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Result:
Albert Einstein 1879
Barack Obama 1961
OPTIONAL, UNION, MINUS
| 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 |
OPTIONAL — Einstein (died 1955) vs Obama (alive); ?deathLabel is unbound for Obama:
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". }
}
Result:
Albert Einstein 1955-04-18
Barack Obama (unbound)
MINUS — Nobel laureates minus the French ones:
SELECT ?personLabel WHERE {
?person wdt:P166 wd:Q7191 .
MINUS { ?person wdt:P27 wd:Q142 . }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
LIMIT 3
Result:
Nobel Prize winner
Adam Bernau
Santiago Carril
UNION — dogs AND cats in one result set:
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
Result:
dog 553
cat 239
Gotcha: the default between triple patterns is AND (join) — use UNION for alternatives.
Gotcha:
FILTER NOT EXISTSdiffers fromMINUSwhen variables are unbound — prefer MINUS for set-difference semantics.
Property paths
| 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:P41 | either property |
| ^wdt:P40 | inverse direction |
| !wdt:P40 | any property except P40 |
A path chains several properties into one pattern. The dog example chains "instance of" (wdt:P31) with "subclass of" (wdt:P279) — first understand each step, then the combination:
| Pattern | What it matches | Live example | Returns |
|---|---|---|---|
?x wdt:P31 wd:Q144 |
individual things that are dogs (instance of) | ?x wdt:P31 wd:Q144 |
Daddy, Dempsey, Diamond |
?x wdt:P279 wd:Q144 |
classes that are kinds of dog (subclass of) | ?x wdt:P279 wd:Q144 |
Rottweiler, Swedish Vallhund |
?x wdt:P279* wd:Q144 |
classes that are dog or any kind-of-kind-of-dog (transitive) | ?x wdt:P279* wd:Q144 |
breeds + sub-breeds (Standard Schnauzer, …) |
?x wdt:P31/wdt:P279* wd:Q144 |
individual things that are dogs, of any breed (sequence: instance of, then subclass of*) | ?x wdt:P31/wdt:P279* wd:Q144 |
Theo, Tich, Tickle Em Jock |
The combination wdt:P31/wdt:P279* reads
"instance of something that is a dog or a subclass of dog" — every individual
dog, whatever its breed:
SELECT ?thing ?thingLabel WHERE {
?thing wdt:P31/wdt:P279* wd:Q144 .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
LIMIT 3
Result:
Theo
Tich
Tickle Em Jock
Gotcha: variables used only inside a property path (e.g.
?s wdt:P40/wdt:P40 ?o) cannot be selected.
Aggregates
Aggregates collapse many rows into one per group. All examples use the same three countries (China, US, India).
COUNT — how many values (the running example counts instances per
animal; here: values of wdt:P1082 for the three countries):
SELECT (COUNT(?population) AS ?n) WHERE {
VALUES ?country { wd:Q148 wd:Q30 wd:Q668 }
?country wdt:P1082 ?population .
}
Result:
3
SUM — combined population of the three:
SELECT (SUM(?population) AS ?total) WHERE {
VALUES ?country { wd:Q148 wd:Q30 wd:Q668 }
?country wdt:P1082 ?population .
}
Result:
3071094235
AVG — mean population of the three:
SELECT (AVG(?population) AS ?avg) WHERE {
VALUES ?country { wd:Q148 wd:Q30 wd:Q668 }
?country wdt:P1082 ?population .
}
Result:
1023698078.33
MIN / MAX — smallest and largest of the three:
SELECT (MIN(?population) AS ?min) (MAX(?population) AS ?max) WHERE {
VALUES ?country { wd:Q148 wd:Q30 wd:Q668 }
?country wdt:P1082 ?population .
}
Result:
340110988 1404890000
SAMPLE — one arbitrary value (useful to squash duplicates):
SELECT (SAMPLE(?countryLabel) AS ?anyCountry) WHERE {
VALUES ?country { wd:Q148 wd:Q30 wd:Q668 }
?country wdt:P1082 ?population .
?country rdfs:label ?countryLabel .
FILTER(LANG(?countryLabel) = "en")
}
Result:
United States
GROUP_CONCAT — Einstein's awards in 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
Result:
Albert Einstein Nobel Prize in Physics, …
GROUP BY + HAVING — the running example, filtered to groups with more than 400 instances:
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)
Result:
dog 553Gotcha: aggregates need GROUP BY for every non-aggregated variable; forgetting one mixes unrelated rows.
Subqueries
A query inside a query — useful for "the X with the max Y" patterns.
The most populous country, computed via a subquery:
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". }
}Result:
China 1404890000SERVICE (labels, federation)
The label service turns entity IDs into human-readable labels — used in most queries above:
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
# then reference ?xLabel for every ?x in the query# 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")
}
}Further reading
- Wikidata SPARQL tutorial — the recommended tutorial
- SPARQL 1.1 Query Language — official spec
- Wikidata Query Service — the example endpoint used here
- Help:Contributing/query — querying a different instance (endpoint, prefixes, label service)