Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind Multiple SPARQL Variables into One

Tags:

sparql

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)
    }
  }
}
like image 840
Bondolin Avatar asked Jul 16 '13 11:07

Bondolin


2 Answers

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" |
-----------------
like image 73
Joshua Taylor Avatar answered Oct 23 '22 11:10

Joshua Taylor


I think that you are using the VALUES keyword correctly, but I suspect that there is a short coming in your engine. Are you using SESAME?

However you can work around it by using the BIND coupled with UNION (again!)

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

    {
        {
            BIND(?s1 AS ?s)
        }
        union
        {
            BIND(?s2 AS ?s)
        }
        union
        {
            BIND(?s3 AS ?s)
        }
    }
}
like image 23
user2316243 Avatar answered Oct 23 '22 12:10

user2316243