18

In SPARQL we can do something like this

select * where {
    ?s   (_:prop1 | _:prop2)  "some_val" .
    ...
    #use ?s in other patterns
    ?s    ?o    ?p .
}

Is it possible to do the same for the object part of the pattern? And what are some workarounds of this in case it is not possible?

For example:

select * where {
    ?s   _:prop ("v1" | "v2") .
    ...
    #use ?s in other patterns
    ?s    ?o    ?p .
}
0xFF
  • 3,980
  • 6
  • 38
  • 57

2 Answers2

27

There are a few ways to do this. The simplest and pure SPARQL 1.0 method is to use UNION e.g.

SELECT * WHERE
{
  { ?s _:prop "v1" } UNION { ?s _:prop "v2" }

  # Use ?s in other patterns
}

This is probably the simplest method but if you need multiple constraints on ?s this can quickly get unwieldy.

Second method is to use the IN function in a FILTER clause, this requires a SPARQL 1.1 implementation e.g.

SELECT * WHERE
{
  ?s _:prop ?value .
  FILTER(?value IN ("v1", "v2"))

  # Use ?s in other patterns
}

Problem here is that using IN can perform very poorly if you have many alternatives or a lot of data that may be matched by ?s _:prop ?value

Aside - Many optimisers will actually expand this second method into the first method under the hood.

Third method is to use the VALUES clause which again requires a SPARQL 1.1 implementation:

SELECT * WHERE
{
  VALUES (?value) { ( "v1" ) ( "v2 " ) }
  ?s _:prop ?value .

  # Use ?s in other patterns
}

This is likely the best option since it scales to many alternatives better (depending on your SPARQL implementation) and is maybe the nicest to read and write.

RobV
  • 26,016
  • 10
  • 71
  • 114
4

This works well:

SELECT *
WHERE
{
    VALUES ?value
    {
       "value1"
       "value2"
       "etc"
    }

    ?s ?p ?value
}
Justas
  • 4,793
  • 2
  • 29
  • 33