Search code examples
rdfsparqlowl

How to subquery or combine some queries on SPARQL?


I'm looking to create a Query on SPARQL to find all alerts which the creation date is superior to the alert whose identified by _messageid = "58002774-4fea-11e4-BDAC" (i Don't know its creation date).

I tested queries below and work fine :

Query 1 : Display all the alerts and their creation date :

SELECT ?a ?ct
WHERE {
  ?a :CreateTimeSlot ?cts.
  ?cts :Text ?ct.
}

Query 2 : Display the creation date of the alert that is identified by _messageid = "58002774-4fea-11e4-BDAC":

SELECT ?a ?ct
WHERE {
  ?a :_messageid "58002774-4fea-11e4-bdac".
  ?a :CreateTimeSlot ?cts.
  ?cts :Text ?ct.
}

Query 3 : Display all alertes having creation date superior to the date "2014-10-09T15:15:00":

SELECT ?a ?ct
WHERE {
  ?a :CreateTimeSlot ?cts.
  ?cts :Text ?ct.
  FILTER ( xsd:dateTime(?ct) > xsd:dateTime("2014-10-09T15:15:00") ).
}

the problem is that i don't knew how to combine them to resolve my problem (find all alerts which the creation date is superior to the alert whose identified by _messageid = "58002774-4fea-11e4-BDAC")

I tested some request (described below) by they don't work :

Query 4 :

SELECT ?a ?ct
WHERE {
  ?a :CreateTimeSlot ?cts.
  ?cts :Text ?ct.
  FILTER ( xsd:dateTime(?ct) > {SELECT ?ct2 WHERE { ?a2 :_messageid "58002774-4fea-11e4-bdac". ?a2 :CreateTimeSlot ?cts2. ?cts2 :Text ?ct2 } } )
}

Query 5 :

SELECT ?a ?ct
WHERE {
  ?a :CreateTimeSlot ?cts.
  ?cts :Text ?ct.
  FILTER ( xsd:dateTime(?ct) > xsd:dateTime({SELECT ?ct2 WHERE { ?a2 :_messageid "58002774-4fea-11e4-bdac". ?a2 :CreateTimeSlot ?cts2. ?cts2 :Text ?ct2 } }) )
}

Query 6 :

SELECT ?a
WHERE
{
  {
    SELECT ?a ?ct1
    WHERE
    {
      ?a :CreateTimeSlot ?cts.
      ?cts :Text ?ct1.
    }
    GROUP BY ?a 
  }.
  {
    SELECT ?a ?ct2
    WHERE
    {
      ?a :_messageid "58002774-4fea-11e4-bdac".
      ?a :CreateTimeSlot ?cts.
      ?cts :Text ?ct2.
    }
    GROUP BY ?a
  }.
  FILTER (xsd:dateTime(?ct1) > xsd:dateTime(?ct2)). 
}

Solution

  • Update

    It sounds like you want to retrieve the creation date for the element with the specified messageId, and then get all the elements with a later creation date. That's just this:

    SELECT ?a ?cts ?dc
    WHERE {
      ?x :CreateTimeSlot ?y.
      ?y :_messageid "58002774-4fea-11e4-bdac".
      ?y :Text ?xdate.
    
      ?a :CreateTimeSlot ?cts.
      ?cts :Text ?dc.
      FILTER ( xsd:dateTime(?dc) > xsd:dateTime(?xdate) ).
    }
    

    That can be be cleaned up a bit with some blank nodes:

    SELECT ?a ?cts ?dc
    WHERE {
      [] :CreateTimeSlot [ :_messageid "58002774-4fea-11e4-bdac" ;
                           :Text ?xdate ] .
    
      ?a :CreateTimeSlot ?cts.
      ?cts :Text ?dc.
      FILTER ( xsd:dateTime(?dc) > xsd:dateTime(?xdate) ).
    }
    

    and if you don't need the ?cts, you can simplify as before with:

    SELECT ?a ?cts ?dc
    WHERE {
      [] :CreateTimeSlot [ :_messageid "58002774-4fea-11e4-bdac" ;
                           :Text ?xdate ] .
    
      ?a :CreateTimeSlot/:Text ?dc.
      FILTER ( xsd:dateTime(?dc) > xsd:dateTime(?xdate) ).
    }
    

    Original

    If I understand what you're trying to do, it's just this:

    SELECT ?a ?cts ?dc
    WHERE {
      ?a :CreateTimeSlot ?cts.
      ?a :_messageid "58002774-4fea-11e4-bdac".
      ?cts :Text ?dc.
      FILTER ( xsd:dateTime(?dc) > xsd:dateTime("2014-10-09T15:15:00") ).
    }
    

    There was a little bit of confusion about whether the value of the text property was going to be called ?dc or ?ct, so I went with ?dc.

    There are actually a few ways to clean this up, though. This is just a matter of style, but I'd probably write this as (note the ; syntax to select multiple properties on ?a and the xsd:dateTime literal in the comparison):

    SELECT ?a ?cts ?dc
    WHERE {
      ?a :CreateTimeSlot ?cts ; 
         :_messageid "58002774-4fea-11e4-bdac".
      ?cts :Text ?dc
      FILTER ( xsd:dateTime(?dc) > "2014-10-09T15:15:00"^^xsd:dateTime )
    }
    

    If you don't actually need the ?cts value, you can simplify this even more:

    SELECT ?a ?cts ?dc
    WHERE {
      ?a :CreateTimeSlot/:Text ?dc ;
         :_messageid "58002774-4fea-11e4-bdac".
      FILTER ( xsd:dateTime(?dc) > "2014-10-09T15:15:00"^^xsd:dateTime )
    }