SPARQL Notes I made while watching Wouter Beek’s series on SparQL . It should be noted
Terms Syntax:
?variable
<absolute-uri>
end of a tripple pattern.
repeat the subject;
repeat the subject and predicate,
?s ?p ?o –> subject/predicate/object
Notation
Example
Absolute IRI
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
Relative IRI
<type>
(requires base)
Prefixed IRI
rdf:type
(requires prefix)
Type IRI
a
(only in predicate position)
(Table imported from this video )
Symbol
Notation type
.
Simple triple
;
Predicate list
,
Object list
(Table imported from this video )
Example
Datatype IRI
false
xsd:boolean
11
xsd:integer
1.1
xsd:decimal
1.1e0
xsd:double
“abc”
xsd:string
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
(Table imported from here )
Okay so one thing you have to understand is that you can’t look at sparql like most code where it goes line-by-line. The entire thing gets parsed at once
Don’t interpet it as an SQL database. Just because a Record has a property called Track, doesn’t mean you can query for Tracks.
Also it’s case sensitive! mo:Record & mo:track work. mo:record & mo:Track breaks. (Usually, a capital means it’s a type, and a non-capital means it’s a predicate)
There are somewhat-standardised prefixes. See the Linked Open Vocabularies vocabs page (for some/all of them?)
Structure Note: you can test out the triplydb/pokemon examples here
Okay, the value you provide and where you put ?variables changes things
1 2 3 WHERE { ?thing rdf:type ?type . }
Queries everything with rdf:type for example
Basic spo select 1 2 3 4 5 6 # Prologue SELECT ?s ?p ?o { # Projection: columns ?s ?p ?o. # Pattern : cells/ content } limit x # Modifier: affects rows
Filter select on object value
?p can be replaced with a predicate uri: ?p –> https://triplydb.com/academy/pokemon/vocab/colour
?o can be replaced with a specific object: ?0 –> “yellow”1 2 3 select ?pokemon { ?pokemon < https:/ / triplydb.com/ academy/ pokemon/ vocab/ colour> "yellow" }
Bind (assigning variables) 1 2 3 4 5 select ?pokemon ?color ? greeting { ?pokemon < https:/ / triplydb.com/ academy/ pokemon/ vocab/ colour> ?color. bind("Hi!" as ?greeting) } limit 10
Literal string interpretation 1 2 3 4 select ?location { # "literal"^ ^ < how- to - interpet> bind("Point(4.8649 52.33287)"^ ^ < http:/ / www.opengis.net/ ont/ geosparql#wktLiteral> as ?location) }
Bind calculation 1 2 3 4 select ?pokemon ?weightKilograms ?weightPounds { ?pokemon <https://triplidb.com/academy/pokemon/vocab/weight> ?weightKilograms. bind(?weightKilograms * "2.20462"^^<http://www.w3.org/2001/XMLSchema#float> as ?weightPounds) }
Query against multiple of the same, only returning when there are multiple but allowing switching around/duplicate 1 2 3 4 5 6 7 select ?color ?cry ?name ?type1 ?type2 { ?pokemon < https:/ / triplydb.com/ academy/ pokemon/ vocab/ colour> ?color. ?pokemon < https:/ / triplydb.com/ academy/ pokemon/ vocab/ cry> ?cry. ?pokemon < http:/ / www.w3.org/ 2000 / 01 / rdf- schema#label> ?name. ?pokemon < https:/ / triplydb.com/ academy/ pokemon/ vocab/ type> ?type1. ?pokemon < https:/ / triplydb.com/ academy/ pokemon/ vocab/ type> ?type2. }
Get an object from an object of an object 1 2 3 4 5 6 7 8 9 select ?color ?cry ?name ?type1Name ?type2Name { ?pokemon < https:/ / triplydb.com/ academy/ pokemon/ vocab/ colour> ?color. ?pokemon < https:/ / triplydb.com/ academy/ pokemon/ vocab/ cry> ?cry. ?pokemon < http:/ / www.w3.org/ 2000 / 01 / rdf- schema#label> ?name. ?pokemon < https:/ / triplydb.com/ academy/ pokemon/ vocab/ type> ?type1. ?pokemon < https:/ / triplydb.com/ academy/ pokemon/ vocab/ type> ?type2. ?type1 < http:/ / www.w3.org/ 2000 / 01 / rdf- schema#label> ?type1Name. ?type2 < http:/ / www.w3.org/ 2000 / 01 / rdf- schema#label> ?type2Name. }
Abbrevations Use prefixes to shorten the previous query Most prefixes end with / or #
1 2 3 4 5 6 7 8 9 10 11 prefix rdfs: < http:/ / www.w3.org/ 2000 / 01 / rdf- schema#> prefix vocab: < https:/ / triplydb.com/ academy/ pokemon/ vocab/ > select ?color ?cry ?name ?type1Name ?type2Name { ?pokemon vocab:colour ?color. ?pokemon vocab:cry ?cry. ?pokemon rdfs:label ?name. ?pokemon vocab:type ?type1. ?pokemon vocab:type ?type2. ?type1 rdfs:label ?type1Name. ?type2 rdfs:label ?type2Name. }
Use base IRI 1 2 3 4 5 6 7 8 9 10 11 base < https:/ / triplydb.com/ academy/ pokemon/ vocab/ > prefix rdfs: < http:/ / www.w3.org/ 2000 / 01 / rdf- schema#> select ?color ?cry ?name ?type1Name ?type2Name { ?pokemon < colour> ?color. ?pokemon < cry> ?cry. ?pokemon rdfs:label ?name. ?pokemon < type> ?type1. ?pokemon < type> ?type2. ?type1 rdfs:label ?type1Name. ?type2 rdfs:label ?type2Name. }
Empty alias 1 2 3 4 5 6 7 8 9 10 11 base < https:/ / triplydb.com/ academy/ pokemon/ vocab/ > prefix : < http:/ / www.w3.org/ 2000 / 01 / rdf- schema#> select ?color ?cry ?name ?type1Name ?type2Name { ?pokemon < colour> ?color. ?pokemon < cry> ?cry. ?pokemon :label ?name. ?pokemon < type> ?type1. ?pokemon < type> ?type2. ?type1 :label ?type1Name. ?type2 :label ?type2Name. }
Special IRI: rdf type <http://www.3.org/1999/02/22-rdf-syntax-ns#type>
-> a (This can only be used in the predicate position, not object or subject)
1 2 3 4 5 6 7 8 9 10 11 12 base < https:/ / triplydb.com/ academy/ pokemon/ vocab/ > prefix : < http:/ / www.w3.org/ 2000 / 01 / rdf- schema#> select ?color ?cry ?name ?type1Name ?type2Name { ?pokemon a ?class. ?pokemon < colour> ?color. ?pokemon < cry> ?cry. ?pokemon :label ?name. ?pokemon < type> ?type1. ?pokemon < type> ?type2. ?type1 :label ?type1Name. ?type2 :label ?type2Name. }
In literals 1 2 3 4 prefix geo: < http:/ / www.opengis.net/ ont/ geosparql#> select ?location { bind("Point(4.8649 52.33287)"^ ^ geo:wktLiteral as ?location) }
End-of-lines 1 2 3 4 5 6 7 8 9 10 11 12 base <https://triplydb.com/academy/pokemon/vocab/> prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> select ?color ?cry ?name ?type1Name ?type2Name { ?pokemon a ?class; <colour> ?color; <cry> ?cry; rdfs:label ?name; <type> ?type1, # You could also type <type> ?type1, ?type2 on one line ?type2. ?type1 rdfs:label ?type1Name, ?type2Name. }
Literal abbrevations (see table above) 1 2 3 4 5 6 prefix vocab: < https:/ / triplydb.com/ academy/ pokemon/ vocab/ > prefix xsd: < http:/ / www.w3.org/ 2001 / XMLSchema#> select ?pokemon { # ?pokemon vocab:weight "80"^ ^ xsd:integer. ?pokemon vocab:weight 80. }
Bind + functions + html 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 PREFIX rdf: < http:/ / www.w3.org/ 1999 / 02 / 22 - rdf- syntax- ns#> PREFIX xsd: < http:/ / www.w3.org/ 2001 / XMLSchema#> PREFIX foaf: < http:/ / xmlns.com/ foaf/ 0.1 / > prefix vocab: < https:/ / triplydb.com/ academy/ pokemon/ vocab/ > prefix rdfs: < http:/ / www.w3.org/ 2000 / 01 / rdf- schema#> select ?color ?name ?text ?widget { ?pokemon vocab:colour ?color; vocab:cry ?cry; rdfs:label ?name; foaf:depiction ?image. bind(concat("Hi!", " ", ?name) as ?text) # bind(concat("202", "0")^ ^ xsd:gYear as ?widget) # # bind(strdt(concat("202", "0"), xsd:gYear) as ?widget) # bind(strdt(concat("<h2 style='color:", ?color, "'>", ?name, "</h2><img src='", str(?image), "'><audio controls><source src='", str(?cry), "'></audio>"), rdf:HTML) as ?widget) } limit 10
Discover all available predicates 1 2 3 4 prefix mo: < http:/ / purl.org/ ontology/ mo/ > SELECT DISTINCT ?p { ?record a mo:Record; ?p ?o. }
(Thanks Felix!)
Also check out Sparklis & its examples ! (Thanks Claire!)
Thanks to Wouter Beeks video series as well as my colleagues for not banning me from the rocket chat for my questions
Here’s some other queries I made that don’t fit in the above because they work but I barely understand them myself but they might contain wisdom somewhere
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 PREFIX rdf: < http:/ / www.w3.org/ 1999 / 02 / 22 - rdf- syntax- ns#> PREFIX rdfs: < http:/ / www.w3.org/ 2000 / 01 / rdf- schema#> prefix mo: < http:/ / purl.org/ ontology/ mo/ > prefix dc: < http:/ / purl.org/ dc/ elements/ 1.1 / > SELECT ?title (SUM (?duration)/ 1000 / 60 AS ?total_duration_in_min) { ?record a mo:Record; dc:title ?title; mo:track ?track. ?track mo:duration ?duration. } GROUP BY ?titleHAVING ((SUM (?duration)/ (1000.0 * 60.0 )) < 60 )ORDER BY DESC (?total_duration_in_min)LIMIT 10
(Thanks Claire, Riad and Niels for dealing with my spam about this)