Reputation: 2431
If I have this data:
:a :p :x; a :C .
:b :p :y; a :C .
:c :p :y; a :C .
:d :q :z; a :C .
:e :p :y; a :C .
How to make a SPARQL query to select the first ?s :p :y
and exclude any other.
In other words, how to change this query:
SELECT *
WHERE {?s a :C}
so that on this data, there should be only two results, :d
and either :b
or :c
or :e
. It doesn't matter which, as it depends on the order of matching against the pattern, which I guess is outside the control of the query.
Note: I'm simplifying the actual case, where there is a set of patterns, not just ?s a :C, but the idea is, if some matching triples are also linked with :p
, there should be one result for identical ?o
in the ?s :p ?o
pattern.
Upvotes: 1
Views: 619
Reputation: 85843
You can group by ?p and ?o and then sample from the ?s values in each group:
select (sample(?s_) as ?s) ?p ?o where {
?s_ a :C .
?s_ ?p ?o.
#-- Filter here is used to exclude the property that was used
#-- for selecting individuals (?s_ a :C). In general, this
#-- just needs to make sure that the selection criteria aren't
#-- the same as what we're grouping on. If the candidate values
#-- of ?p are known in advance, this could replaced by
#-- `values ?p { :p :q ... }`.
filter(?p != rdf:type)
}
group by ?p ?o
Upvotes: 4
Reputation: 2277
You can use LIMIT
to limit the results to only one row:
SELECT ?s {
?s :p :y .
} LIMIT 1
You can use ORDER BY
to affect the order of the results and thus the resource that will be selected.
Upvotes: 0