13

In this simple sparql query I get a list of subjects whose object is 42

SELECT ?v WHERE { ?v ?p 42 }

If I add ?p as a variable

SELECT ?v ?p WHERE { ?v ?p 42 }

I will get two entities per row, the subject and the predicate. What if I wanted three entities, so including the 42? Something like:

SELECT ?v ?p ?m WHERE { ?v ?p (42 as m) }
Stefano Borini
  • 125,999
  • 87
  • 277
  • 404
  • 1
    If 42 is really a constant, why send it forth and back? When you get rows with two elements, you can just add the third. Or is this example oversimplified and you're trying to do something more complicated? – Pēteris Caune Nov 19 '09 at 13:39
  • @StefanoBorini SPARQL 1.0 made this a bit inconvenient, but SPARQL 1.1 includes `values` for just this purpose (and you can specify more than one constant value for the inline data, too). I've added an answer. – Joshua Taylor Mar 03 '14 at 22:48

6 Answers6

17

Another variant is to use BIND, e.g.:

SELECT ?v ?p ?m
WHERE {
  BIND(42 AS ?m)
  ?v ?p ?m
}

The BIND statement simply adds a binding for ?m, which can then be selected for the result set.

scotthenninger
  • 3,613
  • 1
  • 12
  • 23
14

In SPARQL 1.1, you can use VALUES for this. You would write

SELECT ?v ?p ?m WHERE {
  values ?m { 42 }
  ?v ?p ?m
}
Joshua Taylor
  • 80,876
  • 9
  • 135
  • 306
9

Standard SPARQL 1.0 does not really allow that. There may be some implementation-specific extensions for doing it, though.

As a workaround, if the data contains a triple with 42 as an object literal, you can do it e.g. like this:

SELECT ?v ?p ?m { ?v ?p 42, ?m FILTER(?m=42)}

which is equivalent with

 SELECT ?v ?p ?m WHERE { ?v ?p 42 . ?v ?p ?m FILTER(?m=42)}

as you can write graph patterns sharing the same subject and predicate with the comma object list notation, and the WHERE keyword is optional.

For efficiency, you want to use basic graph patterns to reduce the working triple to a smaller set and only then apply FILTER expressions to further prune the results.

laalto
  • 137,703
  • 64
  • 254
  • 280
  • Just realised that this doesn't work properly - this results in selecting any Triples that have the same subject and predicate as those with the object 42 so you potentially get a load of miscellaneous triples which are irrelevant to your query – RobV Dec 07 '09 at 09:34
  • @RobV: True, thanks for pointing that out. I've revised the answer. – laalto Dec 07 '09 at 10:02
3

You can accomplish in two ways using BINDINGS keyword as well as FILTER

Using BINDINGS

SELECT ?v ?p ?m 
WHERE { ?v ?p ?m}
BINDINGS ?m {(42)}

Using FILTER

SELECT ?v ?p ?m
WHERE {
?v ?p ?m
FILTER (?m = 42)
}
  • 2
    [`VALUES` had replaced and generalized `BINDINGS`](https://www.w3.org/TR/2012/WD-sparql11-query-20120724/#status) in the Last Call Working Draft of SPARQL 1.1 Query Language – Stanislav Kralin Jul 31 '17 at 12:54
1
select ?v ?p ?m where { ?v ?p ?m . FILTER( ?m = 42 ) }
Pēteris Caune
  • 38,874
  • 6
  • 52
  • 76
  • 1
    It would seem sensible but depending on your Triple Store and SPARQL engine it is likely to be very inefficient as a lot of SPARQL engines do FILTERs in-memory which means you'd effectively load the entire dataset (since ?v ?p ?m matches everything) and then have to FILTER over all of it for objects which are 42 – RobV Dec 07 '09 at 09:30
  • True, but any SPARQL feature can be inefficient depending on Triple Store. For example, LIMIT and OFFSET seem like sensible things, these should work fast, right? For example on AllegroGraph these are postprocessing instructions, so very slow if you have lots of data. With regards to filter, FILTER, at least on Virtuoso it's very efficient, it translates to very simple SQL query with just two WHERE conditions. – Pēteris Caune Dec 07 '09 at 14:19
  • For a simple FILTER like this then it would translate to a simple SQL query assuming your store is SQL based. LIMIT and OFFSET are typically post-processing in any SPARQL implementation since you need to apply FILTERs and ORDER BYs before you can apply them - I would not expect them to be fast over large datasets. For such a case anyway laalto's approach is more efficient and more portable across different SPARQL implementations – RobV Dec 07 '09 at 23:01
  • I never took a close look at laalto's approach, it didn't look right in the beginning. But yeah, it is indeed better and would work better than mine in general case. – Pēteris Caune Dec 08 '09 at 09:33
  • Well it did have an error in it originally until he edited it the other day – RobV Dec 08 '09 at 13:00
1

I know this is round-about, but I believe this is doable with a subquery.

This is a useful pattern to help you work on the query in the narrow, before you let it loose on your entire dataset:

SELECT ?v ?p ?m WHERE {
   { SELECT 42 as ?m WHERE { } }
   ?v ?p ?m .
}
Jérôme Verstrynge
  • 51,859
  • 84
  • 263
  • 429
  • 2
    Actually, there is a proposal to add to sparql 1.1 to do this more directly. If this ever gets implemented, then you should be able to use "BIND ( 42 AS ?m )" instead of the subquery. http://www.w3.org/TR/sparql11-query/#bind – Doug Whitehead Sep 12 '11 at 20:00
  • 1
    Actually, the **values** form is even nicer, and supports multiple values: `values ?m { 42 } ?v ?p ?m`. – Joshua Taylor Jun 03 '15 at 15:09