Search code examples
sparql

Bind Multiple SPARQL Variables into One


Is there a way of doing something like this:

BIND((?s1, ?s2, ?s3) AS ?s)

such that queries on ?s will be distributed to the list?

EDIT

BTW, it seems the following does not work. Am I doing something wrong?

SELECT *
WHERE
{
  VALUES (?s1 ?s2 ?s3) {(1 4 7) (2 5 8) (3 6 9)} .
  {
    {
      BIND(?s1 AS ?s)
    }
    union
    {
      BIND(?s2 AS ?s)
    }
    union
    {
      BIND(?s3 AS ?s)
    }
  }
}

Solution

  • If you have concrete values to use for ?s, then you can VALUES in SPARQL 1.1. If you don't have concrete values, then you may still be able to do this if you can structure your query so that ?s is generated by a subquery. I'll give an example of each, using this data:

    @prefix : <http://example.org/> .
    
    :t :hasEss :s1, :s2, :s3  .
    :s1 :value "larry" .
    :s2 :value "curly" .
    :s3 :value "moe" .
    

    Using VALUES

    VALUES specifies fixed values for one or more variables.

    prefix : <http://example.org/>
    
    select * where { 
      values ?s { :s1 :s2 :s3 }
      ?s :value ?value
    }
    
    $ arq --data data.n3 --query values.query
    -----------------
    | s   | value   |
    =================
    | :s1 | "larry" |
    | :s2 | "curly" |
    | :s3 | "moe"   |
    -----------------
    

    We're only using one (?s) here, but the syntax also supports more, so in the future, if you have need for it, you can also do

    values (?x ?y) { (:x1 :y1) (:x2 :y2) ... }
    

    Using a subquery

    You could also write a subquery that finds the values of ?s and then the superquery will use those results.

    prefix : <http://example.org/>
    
    select * where { 
      { 
        select ?s where { 
          :t :hasEss ?s
        }
      }
      ?s :value ?value
    }
    
    $ arq --data data.n3 --query subquery.sparql
    -----------------
    | s   | value   |
    =================
    | :s3 | "moe"   |
    | :s2 | "curly" |
    | :s1 | "larry" |
    -----------------