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.