Search code examples
sparqlrdfowl

SPARQL concat plus group_concat on multiple fields


I have the following RDF structure that I cannot change: enter image description here

Multiple Assignments can be associated to each employee (Manager). The output I'd like would be (including the word "in" and "&):

Employee Name   | Assignment

Name 1          | Assignment1 in Location1 & Assignment2 in Location2 &....
Name 2          | Assignment1 in Location2 & Assignment3 in Location1 &....

Is there a way to do this in Sparql?

This is what I have so far:

select ?name group_concat(DISTINCT ?description; separator("&"))
where
{
  ?employee :hasName ?name
  {
  select concat(?name, "In", ?location)
  ?employee ^:hasManager/:hasAsstName ?name
  ?employee ^:hasManager/:hasLocation ?location
  }

}

This gives me empty employee name and lots of ?Descriptions. It does not seem to reflect what I was expecting.


Solution

  • Assuming the nested query is fine, you should assign a variable there to group concatenate and then group the results for all not concatenated variables. The query should look something like this:

    select ?name (group_concat(DISTINCT ?description; separator = " & ") as ?descriptions)
    where
    {
      ?employee :hasName ?name
      {
      select (concat(?name, " in ", ?location) AS ?description)
      ?employee ^:hasManager/:hasAsstName ?name
      ?employee ^:hasManager/:hasLocation ?location
      }
    
    }
    
    GROUP BY ?name
    

    Note the syntax for GROUP_CONCAT.

    If you remove the subquery, it will be much faster. As I don't have your data, here's a very similar query on DBpedia, not using subquery:

    SELECT ?name (GROUP_CONCAT(DISTINCT ?SpouseInfo; separator = " & ") AS ?SpousesInfo)
    
    {
        ?name a foaf:Person;
        dbo:spouse ?spouse.
        ?spouse dbo:residence/rdfs:label ?residence;
        rdfs:label ?spouse_name
    
        BIND (CONCAT(?spouse_name, " lives in ",?residence) AS ?SpouseInfo)
    }
    GROUP BY ?name
    ORDER BY ?name
    
    LIMIT 100
    

    Here's the result.