Using VALUES to map values in a SPARQL query

The VALUES keyword: even better than I thought.

Note: Ebook versions of the “raw, unedited” version of the new expanded edition of my book Learning SPARQL are now available on O’Reilly’s website, and the cooked, edited version (not much different, really) should be available in all formats within a few days. While this edition adds coverage of the VALUES keyword, I came up with the example below too late to include it.)

"if I could just define a little mapping table..."

I recently had to map a few values within a SPARQL query. I didn’t want to do a heavily nested IF() function, and thought “if I could just define a little mapping table…” and then realized that I can, using a new SPARQL 1.1 keyword that I’ve already written about: VALUES.

Let’s say I want to output the names of the people in the following data, not with their associated airport codes, but with the names of those airports’ cities.

@prefix d:  <http://learningsparql.com/ns/data#> .
@prefix dm: <http://learningsparql.com/ns/demo#> .


d:i0432 dm:firstName "Richard" ;
        dm:airport "CHO" . 


d:i9771 dm:firstName "Cindy" ;
        dm:airport "RIC" . 


d:i8301 dm:firstName "Craig" ;
        dm:airport "LYH" . 

What I would really do is use triples associating airport codes with city names to drive the lookup, but storing the lookup information within the query gives some sense of how powerful the VALUES keyword can be for something like this:

PREFIX dm: <http://learningsparql.com/ns/demo#> 


SELECT ?first ?city
WHERE {


  ?person dm:firstName ?first ;
          dm:airport ?airport . 


  VALUES (?airport ?city) {
    ( "CHO" "Charlottesville" )
    ( "RIC" "Richmond" )
    ( "LYH" "Lynchburg" )
  }


}

Running that query on the data above produces this result:

---------------------------------
| first     | city              |
=================================
| "Richard" | "Charlottesville" |
| "Cindy"   | "Richmond"        |
| "Craig"   | "Lynchburg"       |
---------------------------------

Each row in my VALUES table had only two values, and they were both strings, but you can have any number you like—with any types, including URIs. This makes for a lot of possibilities.

So, the next time you’re thinking of adding a heavily nested IF() function to your SPARQL query to account for several possible values of something, consider using SPARQL’s newest keyword. A VALUES table is easier to create, use, and read.