Search code examples
sparqlrdflinked-data

Preferred combination SPARQL


I am trying to write an elegant SPARQL that gives me one solution for multiple possible queries. I have a number of subjects and a number of predicates and I want to receive a single object. The existence of a single solution is very uncertain so I give multiple options. If I am not mistaken, this can be done with the following query:

SELECT ?object
WHERE {
    :subjA|:subjB|:subjC :propA|:propB|:propC ?object.
}
LIMIT 1

The real problem is that I do not want any solution. I want order by :subjA and then :propA. To make it clear; I want the first solution in the following list of combinations:

  • :subjA :propA
  • :subjA :propB
  • :subjA :propC
  • :subjB :propA
  • :subjB :propB
  • :subjB :propC
  • :subjC :propA
  • :subjC :propB
  • :subjC :propC

How to rewrite my query to get the first possible solution?


Solution

  • This is for sure not a valid SPARQL query. You can only use | for the predicate which will then be called a property path but you're losing the variable binding.

    SPARQL returns a set of rows but you can use for example the lexicographical order. Not sure, if this is what you want:

    sample data

    @prefix : <http://ex.org/> .
    
    :subjA :propA :o1 .
    :subjA :propC :o1 .
    :subjB :propB :o1 .
    :subjC :propB :o1 .
    :subjC :propA :o1 .
    :subjA :propC :o2 .
    :subjB :propB :o2 .
    :subjB :propC :o2 .
    

    query

    PREFIX : <http://ex.org/>
    SELECT  ?s ?p ?o
    WHERE
      { VALUES ?s { :subjA :subjB :subjC }
        VALUES ?p { :propA :propB :propC }
        ?s  ?p  ?o
      }
    ORDER BY ?s ?p
    

    result

    -------------------------
    | s      | p      | o   |
    =========================
    | :subjA | :propA | :o1 |
    | :subjA | :propC | :o1 |
    | :subjA | :propC | :o2 |
    | :subjB | :propB | :o1 |
    | :subjB | :propB | :o2 |
    | :subjB | :propC | :o2 |
    | :subjC | :propA | :o1 |
    | :subjC | :propB | :o1 |
    -------------------------
    

    Update

    Since a used-defined order is wanted, as a workaround an index for entities can be used (I changed the order of :subjB and :subjC resp. :propB and :propC to show the difference compared to lexicographical order):

    query

    PREFIX : <http://ex.org/>
    SELECT  ?s ?p ?o
    WHERE
      { VALUES (?sid ?s) { (1 :subjA) (2 :subjC) (3 :subjB) }
        VALUES (?pid ?p) { (1 :propA) (2 :propC) (3 :propB) }
        ?s  ?p  ?o
      }
    ORDER BY ?sid ?pid
    

    result

    -------------------------
    | s      | p      | o   |
    =========================
    | :subjA | :propA | :o1 |
    | :subjA | :propC | :o1 |
    | :subjA | :propC | :o2 |
    | :subjC | :propB | :o1 |
    | :subjC | :propA | :o1 |
    | :subjB | :propB | :o1 |
    | :subjB | :propB | :o2 |
    | :subjB | :propC | :o2 |
    -------------------------