- From: Aidan Hogan <aidhog@gmail.com>
- Date: Sun, 8 Aug 2021 20:39:38 -0400
- To: public-sparql-dev@w3.org, joylix <joylix@126.com>
Hi Joylix,
I think that the solution gets a bit more difficult, but if you are
working with integers, you could try to query the values like this:
PREFIX : <http://example.org/#>
SELECT ?student ?test ?grade
WHERE {
?student :tookTest ?test .
?test :score ?score .
?range a :range .
?range :grade ?grade .
{ ?range :maxInclusive ?max }
UNION
{ ?range :maxExclusive ?maxExc . BIND(?maxExc - 1 AS ?max) }
{ ?range :minInclusive ?min }
UNION
{ ?range :minExclusive ?minExc . BIND(?minExc + 1 AS ?min) }
FILTER(?score >= ?min && ?score <= ?max)
}
Another option (that would work also for non-integer values) would be to
expand the FILTER.
PREFIX : <http://example.org/#>
SELECT ?student ?test ?grade
WHERE {
?student :tookTest ?test .
?test :score ?score .
?range a :range .
?range :grade ?grade .
{ ?range :maxInclusive ?maxInc }
UNION
{ ?range :maxExclusive ?maxExc }
{ ?range :minInclusive ?minInc }
UNION
{ ?range :minExclusive ?minExc }
FILTER(
(!isBound(?minInc) || (?score >= ?minInc)) &&
(!isBound(?minExc) || (?score > ?minExc)) &&
(!isBound(?maxInc) || (?score <= ?maxInc)) &&
(!isBound(?maxExc) || (?score < ?maxExc))
)
}
Best,
Aidan
On 2021-08-08 11:42, joylix wrote:
> Dear Aidan, Thank you very much for the solution.
> Also, in this case, I still don't know how to deal with the limit of
> boundary.
> If I need to consider the inclusive and exclusive values of limit as:
> :range1 a :range ;
> :grade "A" ;
> :minInclusive 90 ;
> :maxInclusive 100.
> :range2 a :range ;
> :grade "B" ;
> :minInclusive 75 ;
> :maxExclusive 90 .
> :range3 a :range ;
> :grade "C" ;
> :minInclusive 60 ;
> :maxExclusive 75 .
> :range4 a :range ;
> :grade "D" ;
> :minInclusive 0 ;
> :maxExclusive 60 .
> How can I write logical operators in A SPARQL statement based on
> different predicates (inclusive or exclusive)?
> FILTER(?score >= ?lower && ?score <= ?upper)
> So this part of the SPARQ statement ">=" is sometimes ">", "<=" can
> also be "<". Is there an easy way to deal with this situation?
> I thought it might be easy to implement this example with shacl, but I
> didn't know how.
> Thanks again for your reply and help.
>
> Kind regards,
> Joylix
>
>
>
>
>
> At 2021-08-07 06:11:22, "Aidan Hogan" <aidhog@gmail.com> wrote:
>>Hi Joylix,
>>
>>You could try something like:
>>
>>PREFIX : <http://example.org/#>
>>SELECT ?student ?test ?grade
>>WHERE {
>> ?student :tookTest ?test .
>> ?test :score ?score .
>> ?range a :range .
>> ?range :grade ?grade .
>> ?range :lowerLimit ?lower .
>> ?range :upperLimit ?upper .
>> FILTER(?score >= ?lower && ?score <= ?upper)
>>}
>>
>>Not tested, but I think this should work.
>>
>>Best,
>>Aidan
>>
>>P.S., if you want to express rules over RDF (in RDF) and like to use
>>SPARQL for that, you might be interested in SPIN:
>>
>>https://www.w3.org/Submission/spin-sparql/
>>
>>
>>On 2021-08-06 4:23, joylix wrote:
>>> Dear all, I have some data on students' test scores as follows:
>>>
>>>
>>> /@prefix : <http://example.org/#> ./
>>>
>>> /:Bob a :Student;/
>>>
>>> / :tookTest :Test0,:Test1,:Test2 ,:Test3 ./
>>>
>>> /:Test0 :score 90 ./
>>>
>>> /:Test1 :score 81 ./
>>>
>>> /:Test2 :score 62 ./
>>>
>>> /:Test3 :score 32 ./
>>>
>>> The rules for grading based on scores are as follows:
>>>
>>> [90-100] --> A
>>>
>>> [75-90) --> B
>>>
>>> [60-75) --> C
>>>
>>> [0-60) --> D
>>>
>>> So I used the following SPARQL query to get the grade of the student's Test:
>>>
>>>
>>> /prefix : <http://example.org/#>/
>>>
>>> /select ?student ?test ?grade/
>>>
>>> / WHERE { /
>>>
>>> / ?student :tookTest ?test ./
>>>
>>> / ?test :score ?score ./
>>>
>>> / BIND ( IF ( ?score >= 90 , "A", IF ( ?score>=75, "B", IF (
>>> ?score>=60, "C", "D" ) ) ) AS ?grade )/
>>>
>>> / }/
>>>
>>> And I got the right result as such:
>>>
>>>
>>> student, test, grade
>>>
>>> http://example.org/#Bob, http://example.org/#Test3, D
>>>
>>> http://example.org/#Bob, http://example.org/#Test2, C
>>>
>>> http://example.org/#Bob, http://example.org/#Test1, B
>>>
>>> http://example.org/#Bob, http://example.org/#Test0, A
>>>
>>> Now my question is how to store this rule data in RDF (along with
>>> the score) rather than in SPARQL, so that the rule data can be defined
>>> and modified by the user, The server side reads the rule data to
>>> generate the appropriate SPARQL query.
>>>
>>> My initial thoughts are as follows:
>>>
>>>
>>> / :range1 a :range ;/
>>>
>>> / :grade "A" ;/
>>>
>>> / :lowerLimit 90 ;/
>>>
>>> / :upperLimit 100./
>>>
>>> /:range2 a :range ;/
>>>
>>> / :grade "B" ;/
>>>
>>> / :lowerLimit 75 ;/
>>>
>>> / :upperLimit 89 ./
>>>
>>> /:range3 a :range ;/
>>>
>>> / :grade "C" ;/
>>>
>>> / :lowerLimit 60 ;/
>>>
>>> / :upperLimit 74 ./
>>>
>>> /:range4 a :range ;/
>>>
>>> / :grade "D" ;/
>>>
>>> / :lowerLimit 0 ;/
>>>
>>> / :upperLimit 59 ./
>>>
>>> /:rule1 :hasRange :range1,:range2, :range3, :range4 ./
>>>
>>>
>>> But how do I now write the right SPARQL to read the rule and complete
>>> the grade transformation?
>>>
>>> And how to handle with inclusive and exclusive of the boundary of limit?
>>> Thank you for any suggestion.
>>>
>>> Kind regards,
>>> Joylix
>>>
>>>
>>>
>>>
>
>
>
Received on Monday, 9 August 2021 00:39:52 UTC