Solution Sequences and Modifiers
Query patterns generate an unordered collection of solutions, each solution being a partial function from variables to RDF terms. These solutions are then treated as a sequence (a solution sequence), initially in no specific order; any sequence modifiers are then applied to create another sequence. Finally, this latter sequence is used to generate one of the results of a SPARQL query form.
A solution sequence modifier is one of:
- Order modifier: put the solutions in order
- Projection modifier: choose certain variables
- Distinct modifier: ensure solutions in the sequence are unique
- Reduced modifier: permit elimination of some non-distinct solutions
- Offset modifier: control where the solutions start from in the overall sequence of solutions
- Limit modifier: restrict the number of solutions
Modifiers are applied in the order given by the list above.
ORDER BY
The ORDER BY clause establishes the order of a solution sequence.
Following the ORDER BY clause is a sequence of order comparators, composed of an expression and an optional
order modifier (either ASC() or DESC()). Each ordering comparator is either ascending (indicated by the ASC() modifier or by no modifier) or descending (indicated by the DESC() modifier).
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE { ?x foaf:name ?name }
ORDER BY ?name
PREFIX : <http://example.org/ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE { ?x foaf:name ?name ; :empId ?emp }
ORDER BY DESC(?emp)
PREFIX : <http://example.org/ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE { ?x foaf:name ?name ; :empId ?emp }
ORDER BY ?name DESC(?emp)
The "<" operator (see the Operator Mapping and 17.3.1 Operator Extensibility) defines the relative order of pairs of numerics, simple literals, xsd:strings, xsd:booleans and xsd:dateTimes. Pairs of IRIs are ordered by comparing them as simple literals.
SPARQL also fixes an order between some kinds of RDF terms that would not otherwise be ordered:
- (Lowest) no value assigned to the variable or expression in this solution.
- Blank nodes
- IRIs
- RDF literals
A plain literal is lower than an RDF literal with type xsd:string of the same lexical form.
SPARQL does not define a total ordering of all possible RDF terms. Here are a few examples of pairs of terms for which the relative order is undefined:
- "a" and "a"@en_gb (a simple literal and a literal with a language tag)
- "a"@en_gb and "b"@en_gb (two literals with language tags)
- "a" and "1"^^xsd:integer (a simple literal and a literal with a supported datatype)
- "1"^^my:integer and "2"^^my:integer (two unsupported datatypes)
- "1"^^xsd:integer and "2"^^my:integer (a supported datatype and an unsupported datatype)
This list of variable bindings is in ascending order:
| RDF Term | Reason |
|---|---|
| Unbound results sort earliest. | |
_:z |
Blank nodes follow unbound. |
_:a |
There is no relative ordering of blank nodes. |
<http://script.example/Latin> |
IRIs follow blank nodes. |
<http://script.example/Кириллица> |
The character in the 23rd position, "К", has a unicode codepoint 0x41A, which is higher than 0x4C ("L"). |
<http://script.example/漢字> |
The character in the 23rd position, "漢", has a unicode codepoint 0x6F22, which is higher than 0x41A ("К"). |
"http://script.example/Latin" |
Simple literals follow IRIs. |
"http://script.example/Latin"^^xsd:string |
xsd:strings follow simple literals. |
The ascending order of two solutions with respect to an ordering comparator is established by substituting the solution bindings into the expressions and comparing them with the "<" operator. The descending order is the reverse of the ascending order.
The relative order of two solutions is the relative order of the two solutions with respect to the first ordering comparator in the sequence. For solutions where the substitutions of the solution bindings produce the same RDF term, the order is the relative order of the two solutions with respect to the next ordering comparator. The relative order of two solutions is undefined if no order expression evaluated for the two solutions produces distinct RDF terms.
Ordering a sequence of solutions always results in a sequence with the same number of solutions in it.
Using ORDER BY on a solution sequence for a CONSTRUCT or DESCRIBE query has no direct effect because only SELECT returns a sequence of results. Used in combination with LIMIT and OFFSET, ORDER BY can be used to return results generated from a different slice of the solution sequence.
An ASK query does not include ORDER BY, LIMIT or OFFSET.
Projection
The solution sequence can be transformed into one involving only a subset of the variables. For each solution in the sequence, a new solution is formed using a specified selection of the variables using the SELECT query form.
The following example shows a query to extract just the names of people described in an RDF graph using FOAF properties.
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example> .
_:b foaf:name "Bob" .
_:b foaf:mbox <mailto:bob@work.example> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE
{ ?x foaf:name ?name }
| name |
|---|
| "Bob" |
| "Alice" |
Duplicate Solutions
A solution sequence with no DISTINCT or REDUCED query modifier will preserve duplicate solutions.
Data:
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
_:x foaf:name "Alice" .
_:x foaf:mbox <mailto:alice@example.com> .
_:y foaf:name "Alice" .
_:y foaf:mbox <mailto:asmith@example.com> .
_:z foaf:name "Alice" .
_:z foaf:mbox <mailto:alice.smith@example.com> .
Query:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name WHERE { ?x foaf:name ?name }
Results:
| name |
|---|
| "Alice" |
| "Alice" |
| "Alice" |
The modifiers DISTINCT and REDUCED affect whether duplicates are included in the query results.
DISTINCT
The DISTINCT solution modifier eliminates duplicate solutions. Only one solution solution that
binds the same variables to the same RDF terms is returned from the query.
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name WHERE { ?x foaf:name ?name }
| name |
|---|
| "Alice" |
Note that, per the order of solution sequence modifiers, duplicates are eliminated before either limit or offset is applied.
REDUCED
While the DISTINCT modifier ensures that duplicate solutions are eliminated from the solution set, REDUCED simply permits them to be eliminated. The cardinality of any set of variable bindings
in a REDUCED solution set is at least one and not more than the cardinality of the solution set
with no DISTINCT or REDUCED modifier. For example, using the data above, the query
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT REDUCED ?name WHERE { ?x foaf:name ?name }
may have one, two (shown here) or three solutions:
| name |
|---|
| "Alice" |
| "Alice" |
OFFSET
OFFSET causes the solutions generated to start after the specified number of solutions.
An OFFSET of zero has no effect.
Using LIMIT and OFFSET to select different subsets of the query solutions will not be useful unless the
order is made predictable by using ORDER BY.
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE { ?x foaf:name ?name }
ORDER BY ?name
LIMIT 5
OFFSET 10
LIMIT
The LIMIT clause puts an upper bound on the number of solutions returned. If the number of
actual solutions, after OFFSET is applied, is greater than the limit, then at most the limit number of solutions
will be returned.
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE { ?x foaf:name ?name }
LIMIT 20
A LIMIT of 0 would cause no results to be returned. A limit may not be negative.
Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang). This software or document includes material copied from or derived from SPARQL 1.1 Query.