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

Assume the following data:

@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ex:   <http://example.org/> .
@prefix zoo:   <http://example.org/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?

Thanks,
Radu

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: Home | Stardog Documentation Latest

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.

Best,
Pavel

@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!