Skip to content
Advertisement

SPARQL Query, select everything except things that match?

I am getting comfortable writing regular queries in SPARQL, but I’m still having trouble with fancier stuff. My latest problem is trying to select everything except stuff that matches the where clause. For instance, say I want to find all the husbands who like a car color that their wife doesn’t like (I’m working on a proprietary model, so excuse the example and just trust that it makes sense in the real model).

I might have:

<bob> <spouse> <alice>
<bob> <likes> <red>
<alice> <likes> <red>
<carl> <spouse> <dorothy>
<carl> <likes> <blue>
<dorothy> <likes> <yellow>
<eric> <spouse> <fannie>
<eric> <likes> <black>

What’s the query that selects carl and eric, but not bob? Bonus points if you can select blue and black in the same query. Selecting bob would be simply:

select ?husband ?color where {?husband <spouse> ?wife . ?husband <likes> ?color . ?wife <likes> ?color}

What I’m looking for is:

select ?husband ?color where {?husband <spouse> ?wife . ?husband <likes> ?color . NOT (?wife <likes> ?color)}

but obviously that’s wrong. So what’s right?

Advertisement

Answer

One correct answer I found through other sources is something like this:

SELECT ?husband ?color 
WHERE {
    ?husband <spouse> ?wife .
    ?husband <likes> ?color .
    OPTIONAL {
        ?wife <likes> ?wifecolor
        FILTER (?wifecolor = ?color)
    }
    FILTER (!BOUND(?wifecolor))
}

It at least works for eric, but I haven’t test carl.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement