Reputation: 1204
Given three possible objects for triples, foaf:name
, foaf:givenName
, and foaf:familyName
, where statements either have foaf:name
or foaf:givenName
+ foaf:familyName
, e.g.:
<uri1> <foaf:name> "Lolly Loozles" .
<uri2> <foaf:givenName> "Stotly" .
<uri2> <foaf:familyName> "Styles" .
wondering how to write a SPARQL query to return a new variable like pretty_name
that is either the value of foaf:name
or a concatenation of the values from foaf:givenName
and foaf:familyName
.
Resulting in something like:
?o | ?pretty_name
----------------------
<uri1> | Lolly Loozles
<uri2> | Stotly Styles
This is what I have so far, but unsure how to proceed:
PREFIX : <https://example.org/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
# select two variables, not ideal...
SELECT ?foaf_fullName ?pretty_name
WHERE {
# Find all triples
?s ?p ?o .
# Binds
OPTIONAL { ?s foaf:name ?foaf_fullName }
OPTIONAL { ?s foaf:givenName ?givenName }
OPTIONAL { ?s foaf:familyName ?familyName }
# Filter where predicate is part of list
FILTER (?p IN (foaf:name, foaf:givenName, foaf:familyName ) )
# Binds
BIND( CONCAT(?givenName, ' ', ?familyName) AS ?pretty_name ) .
}
I had imagined, and tried, adding another BIND
to add to ?pretty_name
, but the SPARQL engine wouldn't have it:
BIND( ?foaf_fullName AS ?pretty_name ) .
I also had luck writing a CONSTRUCT
statement to get the values I'm looking for, but don't have the ability to write back to this triplestore (for a number of reasons):
CONSTRUCT {
?s :hasPrettyName ?foaf_fullName .
?s :hasPrettyName ?pretty_name .
}
I had thought that CONSTRUCT
could accompany SELECT
, but must have been mistaken?
Any insight or suggestions would much appreciated.
Upvotes: 1
Views: 872
Reputation: 1204
Using @StanislavKralin comment/suggestion to use COALESCE
without IF
clauses works great:
PREFIX : <https://example.org/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
# select two variables, not ideal...
SELECT ?foaf_fullName ?pretty_name
WHERE {
# Find all triples
?s ?p ?o .
# Binds
OPTIONAL { ?s foaf:name ?foaf_fullName }
OPTIONAL { ?s foaf:givenName ?givenName }
OPTIONAL { ?s foaf:familyName ?familyName }
# Filter where predicate is part of list
FILTER (?p IN (foaf:name, foaf:givenName, foaf:familyName ) )
# Binds
BIND( COALESCE(?foaf_fullName, CONCAT(?givenName, ' ', ?familyName)) AS ?pretty_name )
}
Upvotes: 1