0

I am a bit new to sparql Query and I am having a lot of trouble producing a simple data set. Basically here's what I am trying to do. Given the following data structure:

 Data
     -Composition
           -ElementName:"A"
           -Value      :"4"

I want to output something like the following

----------------------- 
| elementName | Value |
 =====================
| "A"         | "1"   |
| "B"         | "2"   |
| "C"         | "3"   |
| "D"         | "4"   |
-----------------------

USing the the following code

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX tpl: <http://www.example.com/1962c0ea39923156f8ef72fa44584f26e7c5ae20#>

SELECT ?elementNameValue ?valueValue
WHERE {
{
?s tpl:Data/tpl:composition/tpl:elementName ?o .
?o rdf:value ?elementNameValue .
}
UNION
 {
?s tpl:Data/tpl:composition/tpl:value ?o .
?o rdf:value ?valueValue .
}
} 

I am outputting

----------------------- 
| elementName | Value |
 =====================
| "A"         |       |
| "B"         |       |
| "C"         |       |
| "D"         |       |
|             | "1"   |
|             | "2"   |
|             | "3"   |
|             | "4"   |
-----------------------

What am i doing wrong? directions to resources are also helpful. using APache-Jena

  • What happens when you write `SELECT ?elementNameValue ?valueValue WHERE { { ?s tpl:Data/tpl:composition/tpl:elementName|tpl:value ?o . ?o rdf:value ?elementNameValue . ?o rdf:value ?valueValue . }` – Artemis May 30 '15 at 10:34

2 Answers2

1

The SPARQL spec is your number one resource.

Regarding your question, the Union construct as per your query is for matching alternatives e.g. ?elementNameValue is bound for solutions from the first branch of the UNION, and ?valueValue for solutions from the second branch.

If you are looking for something in the equivalent of an inner join (e.g. results that match both a name and a value), then removing the union may be what you are after:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX tpl: <http://www.example.com/1962c0ea39923156f8ef72fa44584f26e7c5ae20#>

SELECT ?elementNameValue ?valueValue WHERE {
  ?s tpl:Data/tpl:composition/tpl:elementName ?name .
  ?name rdf:value ?elementNameValue .
  ?s tpl:Data/tpl:composition/tpl:value ?value .
  ?value rdf:value ?valueValue .
} 

which may be optimised:

SELECT ?elementNameValue ?valueValue WHERE {
  ?s tpl:Data/tpl:composition ?o .
  ?o tpl:elementName/rdf:value ?elementNameValue;
     tpl:value/rdf:value ?valueValue . 
} 

This will give you result rows that have both a name and value. See also Joshua Taylor's answer for an alternative form using a blank node variable.

If instead you want something in the equivalent of a full outer join (e.g. results that have either a value or a name or both) then you may look at the Optional construct and formulate your query accordingly. All in the spec and pretty straight forward.

chris
  • 1,787
  • 1
  • 13
  • 13
  • 1
    "assuming the smarty syntax is correct, with which I am not familiar" just curious, which part are you referring to there? – Joshua Taylor May 30 '15 at 12:57
1

Since the query parts:

?s tpl:Data/tpl:composition/tpl:elementName ?o .
?o rdf:value ?elementNameValue .

and

?s tpl:Data/tpl:composition/tpl:value ?o .
?o rdf:value ?valueValue .

are gettting you the parts that you're looking for, I think that you could use a query like this to get the results that you're looking for:

select ?elementName ?value {
  ?s tpl:Data/tpl:composition ?composition .
  ?composition tpl:elementName/rdf:value ?elementName ;
               tpl:value/rdf:value ?value .
}

Now, you can make that even a little bit shorter by using a blank node:

select ?elementName ?value {
  ?s tpl:Data/tpl:composition [ tpl:elementName/rdf:value ?elementName .
                                tpl:value/rdf:value ?value ]
}

But, even better than that, you don't really need the ?s part at all. Unless it's important that the composition node is the value of tpl:composition of some value of tpl:Data, you can just start right at the composition node:

select ?elementName ?value {
  [] tpl:elementName/rdf:value ?elementName ;
     tpl:value/rdf:value ?value .
}
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353