Filtering SPARQL results by day and month

I'm currently using the http://dbpedia.org/snorql website to launch some basic request like the one below:

PREFIX dbpedia0: <http://dbpedia.org/ontology/>
SELECT ?body ?value WHERE {
?body a dbpedia0:Person.
?body dbpedia0:birthDate ?value.
}
ORDER BY ?value

I would like to find a way of filtering the results so that only people born on day X month Y are being selected (no matter the birth year). I have been trying to do so with many approaches like:

1) Basic filtering: FILTER(xsd:date(?value) = "2000-01-01"^^xsd:date) But I don't now how to precise the fact that I don't care about the year...

2) Use the MONTH() and DAY() functions that should lead to integer values representing month and day... But these don't seem to work as my date type is said to be an invalid input argument.

3) Convert the date into a string variable. And then test if the ending characters of this string variable (corresponding to month and day) match the required month and day. That would be something like : FILTER(STRENDS(CONVERT(CHAR, ?value),"01-01") = true)

Apparently, none of the methods listed above is properly working... haha. Please don't blame me for the poor syntax of my request as I'm just beginning with SPARQL commands.

I would be very grateful for any help from on or another over there !!!

Upvotes: 4

Views: 2330

Answers (1)

UninformedUser
UninformedUser

Reputation: 8465

You get an error because (as I said in comment) not all literals are of, or can be CAST to, type xsd:date. A filter for that could work

PREFIX dbpedia0: <http://dbpedia.org/ontology/>
SELECT ?body ?value WHERE 
  { 
    ?body  a                   dbpedia0:Person  . 
    ?body  dbpedia0:birthDate  ?value           . 
           FILTER (   datatype(?value) = xsd:date
                   &&     year(?value) = 2000
                  )
  } 
limit 10

Error:

Virtuoso 22003 Error SR586: Incomplete RDF box as argument 0 for year().

Another try with casting leads me to the impression that the FILTER arguments are executed in arbitrary order, and lead to another error:

PREFIX dbpedia0: <http://dbpedia.org/ontology/>
SELECT ?body ?value 
WHERE 
  { 
    ?body  a                   dbpedia0:Person  . 
    ?body  dbpedia0:birthDate  ?value           . 
           FILTER (         datatype(?value) = xsd:date 
                   && year(xsd:date(?value)) = 2000
                  )
  } 
limit 10

Error:

Virtuoso 22007 Error DT001: Function year needs a datetime, date or time as argument 1, not an arg of type DB_NULL (204)

Using sub-SELECTs seems to work, but not for

PREFIX dbpedia0: <http://dbpedia.org/ontology/>

SELECT ?body ?value 
WHERE 
  { 
           FILTER ( year(xsd:date(?value)) = 2000 )
    { 
      SELECT ?body ?value 
      WHERE 
        { 
          ?body  a                   dbpedia0:Person  . 
          ?body  dbpedia0:birthDate  ?value           . 
                 FILTER ( datatype(?value) = xsd:date )
        }
    }
  }
limit 10

Error:

Virtuoso 22003 Error SR586: Incomplete RDF box as argument 1 for xqf_str_parse().

Only with a LIMIT inside the sub-SELECT it works for me:

PREFIX dbpedia0: <http://dbpedia.org/ontology/>

SELECT ?body ?value 
WHERE 
  { 
           FILTER ( year(xsd:date(?value)) = 2000 )
      {
        SELECT ?body ?value 
        WHERE 
          { 
            ?body  a                   dbpedia0:Person  . 
            ?body  dbpedia0:birthDate  ?value           . 
                   FILTER ( datatype(?value) = xsd:date )
          }
        LIMIT 10
      }
   }
LIMIT 10

I don't know what's going wrong with Virtuoso here.

Upvotes: 2

Related Questions