Bind if one of rdf:type is equal to a specific type

Assume the following data:

@prefix rdf:   <> .
@prefix rdfs:   <> .
@prefix ex:   <> .
@prefix zoo:   <> .

ex:dog1	   rdf:type	    ex:Animal ;  rdf:type ex:Dog .
ex:dog2	   rdf:type	    ex:Animal .

I need sparql select that would bring two rows (dog1 and dog2) with the following columns:

  1. uri
  2. only rdf:type Animal
  3. if concept hasa ex:Dog type then display its type or "Dog" otherwise show empty string.

How do I do that?


select ?animal ?animalType ?dogType where {
    ?animal a ?animalType
     filter(?animalType = ex:Animal)
     optional {
        ?animal a ?dogType
        filter(?dogType = ex:Dog)

I think you may find the sp:directType predicate useful:

Basically ?animal sp:directType ?class will return animals with their most specific type. You can also add ?class rdfs:subClassOf ex:Animal to avoid non-animals.

That'd be a general reasoning solution which would work for any class hierarchy. For that specific example Zach's solution will work too.


@pavel - thanks for sharing! Indeed it makes the sparql code easier to read and maintain.

It worked Zach! Thank you. The magic of "a" - in sparql select - no need of if/else - nice!