Cheatsheets:SPARQL: Difference between revisions
Fix examples: use P1 (instance of) not P31 (subclass of); real class values Q2/Q3 (via update-page on MediaWiki MCP Server) |
Rewrite as generic SPARQL 1.1 syntax cheatsheet (not a tutorial, not instance-coupled); point to Wikidata tutorial + instance guide (via update-page on MediaWiki MCP Server) |
||
| Line 1: | Line 1: | ||
{{Cheatsheet}} | {{Cheatsheet}} | ||
SPARQL 1.1 quick syntax reference — for people who already know what SPARQL is | |||
and need reminders on syntax. For a proper tutorial, take the | |||
[https://www.wikidata.org/wiki/Wikidata:SPARQL_tutorial Wikidata SPARQL | |||
tutorial] (works against any Wikibase endpoint). For querying *this* instance | |||
(endpoint, prefixes, label service), see [[Help:Contributing/query]]. | |||
== | == Query forms == | ||
{| class="wikitable" | |||
! Form !! Returns !! Example | |||
|- | |||
| SELECT || table of variable bindings || <syntaxhighlight lang="sparql" inline>SELECT ?s ?p ?o WHERE { ?s ?p ?o }</syntaxhighlight> | |||
|- | |||
| ASK || boolean — does the pattern match? || <syntaxhighlight lang="sparql" inline>ASK WHERE { ?s ?p ?o }</syntaxhighlight> | |||
|- | |||
| CONSTRUCT || an RDF graph || <syntaxhighlight lang="sparql" inline>CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }</syntaxhighlight> | |||
|- | |||
| DESCRIBE || a graph describing the resource || <syntaxhighlight lang="sparql" inline>DESCRIBE ?s WHERE { ?s ?p ?o }</syntaxhighlight> | |||
|} | |||
== Prefixes & triple patterns == | |||
Prefixes abbreviate IRIs; the binding is endpoint-defined. | |||
<syntaxhighlight lang="sparql"> | <syntaxhighlight lang="sparql"> | ||
PREFIX | PREFIX ex: <http://example.org/> | ||
SELECT ?s ?p ?o WHERE { | |||
SELECT ? | ?s ?p ?o . # triple pattern: subject predicate object | ||
FILTER(?p = ex:age) # constraint on a variable | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
== | Anonymous/blank node as subject or object: <syntaxhighlight lang="sparql" inline>[] ex:age 42</syntaxhighlight>. | ||
Literals can carry datatypes or language tags: | |||
<syntaxhighlight lang="sparql" inline>"text"^^xsd:string</syntaxhighlight>, | |||
<syntaxhighlight lang="sparql" inline>"café"@fr</syntaxhighlight>. | |||
== Solution modifiers == | |||
{| class="wikitable" | {| class="wikitable" | ||
! | ! Clause !! Effect | ||
|- | |- | ||
| | | DISTINCT || drop duplicate solution rows | ||
|- | |- | ||
| | | ORDER BY || sort: <syntaxhighlight lang="sparql" inline>ORDER BY ASC(?x) DESC(?y)</syntaxhighlight> | ||
|- | |- | ||
| | | LIMIT n / OFFSET n || page through results | ||
|- | |- | ||
| | | GROUP BY || group rows for aggregation (see below) | ||
|- | |- | ||
| | | HAVING || filter groups, like WHERE for aggregates | ||
|} | |} | ||
== | == FILTER expressions == | ||
{| class="wikitable" | {| class="wikitable" | ||
! | ! Category !! Examples | ||
|- | |- | ||
| | | comparison || <syntaxhighlight lang="sparql" inline>= < > <= >= !=</syntaxhighlight> | ||
|- | |- | ||
| | | logical || <syntaxhighlight lang="sparql" inline>&& || !</syntaxhighlight> | ||
|- | |- | ||
| | | string || <syntaxhighlight lang="sparql" inline>STR() CONTAINS() STRSTARTS() STRENDS() REGEX()</syntaxhighlight> | ||
|- | |||
| numeric || <syntaxhighlight lang="sparql" inline>ABS() ROUND() FLOOR() CEIL() RAND()</syntaxhighlight> | |||
|- | |||
| date/time || <syntaxhighlight lang="sparql" inline>YEAR() MONTH() DAY() NOW()</syntaxhighlight> | |||
|- | |||
| terms || <syntaxhighlight lang="sparql" inline>isIRI() isBlank() isLiteral() LANG() DATATYPE()</syntaxhighlight> | |||
|} | |} | ||
== | <syntaxhighlight lang="sparql"> | ||
FILTER(CONTAINS(STR(?label), "cat")) | |||
FILTER(LANG(?label) = "fr") | |||
</syntaxhighlight> | |||
== VALUES & BIND == | |||
<syntaxhighlight lang="sparql"> | |||
VALUES ?p { ex:age ex:name } # restrict variable to a list | |||
BIND(?a + ?b AS ?sum) # compute and bind a new variable | |||
</syntaxhighlight> | |||
== OPTIONAL, UNION, MINUS == | |||
<syntaxhighlight lang="sparql"> | |||
?s ex:name ?n . | |||
* | OPTIONAL { ?s ex:age ?a } # left join — ?a missing when absent | ||
{ ?s ex:age ?a } UNION { ?s ex:name ?n } # union of two patterns | |||
?s ?p ?o . | |||
MINUS { ?s ex:age 42 } # remove matches | |||
</syntaxhighlight> | |||
Gotcha: <syntaxhighlight lang="sparql" inline>FILTER NOT EXISTS</syntaxhighlight> vs | |||
<syntaxhighlight lang="sparql" inline">MINUS</syntaxhighlight> differ when a variable is | |||
unbound — prefer <syntaxhighlight lang="sparql" inline>MINUS</syntaxhighlight> for | |||
set-difference semantics. | |||
== Property paths == | |||
{| class="wikitable" | |||
! Path !! Meaning | |||
|- | |||
| <syntaxhighlight lang="sparql" inline>ex:parent/ex:parent</syntaxhighlight> || sequence (length 2) | |||
|- | |||
| <syntaxhighlight lang="sparql" inline>ex:parent+</syntaxhighlight> || one or more | |||
|- | |||
| <syntaxhighlight lang="sparql" inline>ex:parent*</syntaxhighlight> || zero or more | |||
|- | |||
| <syntaxhighlight lang="sparql" inline>ex:parent?</syntaxhighlight> || zero or one | |||
|- | |||
| <syntaxhighlight lang="sparql" inline>ex:p1|ex:p2</syntaxhighlight> || either property | |||
|- | |||
| <syntaxhighlight lang="sparql" inline>^ex:parent</syntaxhighlight> || inverse direction | |||
|- | |||
| <syntaxhighlight lang="sparql" inline>!ex:p1</syntaxhighlight> || any property except p1 | |||
|} | |||
== | == Aggregates == | ||
<syntaxhighlight lang="sparql"> | <syntaxhighlight lang="sparql"> | ||
SELECT ?p (COUNT(?s) AS ?n) (SUM(?x) AS ?total) (SAMPLE(?o) AS ?any) | |||
WHERE { ?s ?p ?o . ?s ex:val ?x } | |||
SELECT ? | GROUP BY ?p | ||
HAVING (COUNT(?s) > 2) | |||
</syntaxhighlight> | </syntaxhighlight> | ||
== | Other aggregates: <syntaxhighlight lang="sparql" inline>AVG() MIN() MAX()</syntaxhighlight>, | ||
<syntaxhighlight lang="sparql" inline>GROUP_CONCAT(?o; SEPARATOR=", ")</syntaxhighlight>. | |||
== Subqueries == | |||
<syntaxhighlight lang="sparql"> | <syntaxhighlight lang="sparql"> | ||
SELECT ?s WHERE { | |||
{ SELECT ?s (MAX(?v) AS ?maxv) WHERE { ?s ex:val ?v } GROUP BY ?s } | |||
SELECT ? | ?s ex:val ?maxv | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Federated queries (SERVICE) == | |||
== | |||
<syntaxhighlight lang="sparql"> | <syntaxhighlight lang="sparql"> | ||
SELECT ?label WHERE { | |||
?s ex:ref ?w . | |||
SERVICE <https://www.wikidata.org/sparql> { | |||
?w rdfs:label ?label . FILTER(LANG(?label) = "en") | |||
} | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Common tasks == | == Common tasks == | ||
* '''Count | * '''Count rows''': <syntaxhighlight lang="sparql" inline>SELECT (COUNT(*) AS ?n) WHERE { ?s ?p ?o }</syntaxhighlight> | ||
* '''Deduplicate''': add <syntaxhighlight lang="sparql" inline>DISTINCT</syntaxhighlight> | |||
* '''Reverse direction''': <syntaxhighlight lang="sparql" inline>?child ^ex:parent ?parent</syntaxhighlight> | |||
* '''Check existence''': <syntaxhighlight lang="sparql" inline>ASK</syntaxhighlight> | |||
* '''JSON output''': append <syntaxhighlight lang="text" inline>&format=json</syntaxhighlight> to the endpoint URL | * '''JSON output''': append <syntaxhighlight lang="text" inline>&format=json</syntaxhighlight> to the endpoint URL | ||
== Gotchas == | == Gotchas == | ||
* ''' | * The default is '''AND (join)''', not OR — use UNION for alternatives. | ||
* | * An unbound variable in <syntaxhighlight lang="sparql" inline">FILTER</syntaxhighlight> makes the row fail (filter is not "true" for unbound) — guard with <syntaxhighlight lang="sparql" inline">BOUND()</syntaxhighlight> or use OPTIONAL. | ||
* | * Variables used only inside a property path (e.g. <syntaxhighlight lang="sparql" inline">?s ex:p1/ex:p2 ?o</syntaxhighlight>) cannot be selected. | ||
* | * Blank-node labels (e.g. <syntaxhighlight lang="sparql" inline">_:x</syntaxhighlight>) are local to one query — they are not IRIs. | ||
* Aggregates require GROUP BY for non-aggregated variables; forgetting it mixes unrelated rows. | |||
* <syntaxhighlight lang="sparql" inline">LIMIT 0</syntaxhighlight> returns no rows but still validates the query. | |||
== Further reading == | == Further reading == | ||
* [https://www.wikidata.org/wiki/Wikidata:SPARQL_tutorial Wikidata SPARQL tutorial] — the recommended tutorial | |||
* [https://www.wikidata.org/wiki/Wikidata:SPARQL_tutorial Wikidata SPARQL tutorial] — | * [https://www.w3.org/TR/sparql11-query/ SPARQL 1.1 Query Language] — official spec | ||
* [https://www.w3.org/TR/sparql11-query/ SPARQL 1.1 spec] | * [[Help:Contributing/query]] — querying this instance (endpoint, prefixes, label service) | ||
Revision as of 11:18, 19 August 2026
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. For a proper tutorial, take the [https://www.wikidata.org/wiki/Wikidata:SPARQL_tutorial Wikidata SPARQL tutorial] (works against any Wikibase endpoint). For querying *this* instance (endpoint, prefixes, label service), see Help:Contributing/query.
Query forms
| Form | Returns | Example |
|---|---|---|
| SELECT | table of variable bindings | SELECT ?s ?p ?o WHERE { ?s ?p ?o }
|
| ASK | boolean — does the pattern match? | ASK WHERE { ?s ?p ?o }
|
| CONSTRUCT | an RDF graph | CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }
|
| DESCRIBE | a graph describing the resource | DESCRIBE ?s WHERE { ?s ?p ?o }
|
Prefixes & triple patterns
Prefixes abbreviate IRIs; the binding is endpoint-defined.
PREFIX ex: <http://example.org/>
SELECT ?s ?p ?o WHERE {
?s ?p ?o . # triple pattern: subject predicate object
FILTER(?p = ex:age) # constraint on a variable
}
Anonymous/blank node as subject or object: [] ex:age 42.
Literals can carry datatypes or language tags:
"text"^^xsd:string,
"café"@fr.
Solution modifiers
| Clause | Effect |
|---|---|
| DISTINCT | drop duplicate solution rows |
| ORDER BY | sort: ORDER BY ASC(?x) DESC(?y)
|
| LIMIT n / OFFSET n | page through results |
| GROUP BY | group rows for aggregation (see below) |
| HAVING | filter groups, like WHERE for aggregates |
FILTER expressions
| Category | Examples |
|---|---|
| comparison | = < > <= >= !=
|
| logical | && || !
|
| string | STR() CONTAINS() STRSTARTS() STRENDS() REGEX()
|
| numeric | ABS() ROUND() FLOOR() CEIL() RAND()
|
| date/time | YEAR() MONTH() DAY() NOW()
|
| terms | isIRI() isBlank() isLiteral() LANG() DATATYPE()
|
FILTER(CONTAINS(STR(?label), "cat"))
FILTER(LANG(?label) = "fr")
VALUES & BIND
VALUES ?p { ex:age ex:name } # restrict variable to a list
BIND(?a + ?b AS ?sum) # compute and bind a new variable
OPTIONAL, UNION, MINUS
?s ex:name ?n .
OPTIONAL { ?s ex:age ?a } # left join — ?a missing when absent
{ ?s ex:age ?a } UNION { ?s ex:name ?n } # union of two patterns
?s ?p ?o .
MINUS { ?s ex:age 42 } # remove matches
Gotcha: FILTER NOT EXISTS vs
MINUS
differ when a variable is
unbound — prefer MINUS for
set-difference semantics.
Property paths
| Path | Meaning |
|---|---|
ex:parent/ex:parent |
sequence (length 2) |
ex:parent+ |
one or more |
ex:parent* |
zero or more |
ex:parent? |
zero or one |
ex:p1|ex:p2 |
either property |
^ex:parent |
inverse direction |
!ex:p1 |
any property except p1 |
Aggregates
SELECT ?p (COUNT(?s) AS ?n) (SUM(?x) AS ?total) (SAMPLE(?o) AS ?any)
WHERE { ?s ?p ?o . ?s ex:val ?x }
GROUP BY ?p
HAVING (COUNT(?s) > 2)
Other aggregates: AVG() MIN() MAX(),
GROUP_CONCAT(?o; SEPARATOR=", ").
Subqueries
SELECT ?s WHERE {
{ SELECT ?s (MAX(?v) AS ?maxv) WHERE { ?s ex:val ?v } GROUP BY ?s }
?s ex:val ?maxv
}
Federated queries (SERVICE)
SELECT ?label WHERE {
?s ex:ref ?w .
SERVICE <https://www.wikidata.org/sparql> {
?w rdfs:label ?label . FILTER(LANG(?label) = "en")
}
}
Common tasks
- Count rows:
SELECT (COUNT(*) AS ?n) WHERE { ?s ?p ?o } - Deduplicate: add
DISTINCT - Reverse direction:
?child ^ex:parent ?parent - Check existence:
ASK - JSON output: append
&format=jsonto the endpoint URL
Gotchas
- The default is AND (join), not OR — use UNION for alternatives.
- An unbound variable in makes the row fail (filter is not "true" for unbound) — guard with
FILTERor use OPTIONAL.BOUND()
- Variables used only inside a property path (e.g. ) cannot be selected.
?s ex:p1/ex:p2 ?o
- Blank-node labels (e.g. ) are local to one query — they are not IRIs.
_:x - Aggregates require GROUP BY for non-aggregated variables; forgetting it mixes unrelated rows.
- returns no rows but still validates the query.
LIMIT 0
Further reading
- Wikidata SPARQL tutorial — the recommended tutorial
- SPARQL 1.1 Query Language — official spec
- Help:Contributing/query — querying this instance (endpoint, prefixes, label service)