Skip to content
Advertisement

How to exclude results in a query using a subquery as blacklist

I’m trying to query a database for text, use a (sub)query as a “blacklist”. The twist: if any of the results from the main query have an identical beginning as any of the results from the subquery, they should be skipped.

A bit of background: I’m building a filebrowser, and using a table of foldernames to maintain the “favorited” state of entries. These favorites are intended to work in a cascading manner, i.e. any paths below a “explicitly” favorited path will be “implicitly” favorited.

Consider the following data:

foldername is_favorite is_implicit_favorite
foo/ 1 0
foo/bar/ 1 1
foo/bar/baz/ 0 1
foo/bar2/ 0 1
foo/bar2/baz/ 0 1
foo2/bar/ 0 0
foo2/bar/baz/ 0 0

Adding a favorite is easy: all folders below the given path will have their “implicit” state set. But I’ve found it hard to come up with a simple approach for the opposite – “unfavoriting” a folder. Because here, I want to the query to skip folders that should remain implicitly favorited (in the example above, unfavoriting “foo/” should skip folders below “foo/bar”).

I’ve tried various solutions – the following approach comes close, but unfortunately only works with a single favorited subfolder:

It does what I want – unfavoriting “foo” should result in “foo/bar2/” and “foo/bar2/baz/” no longer being implicitly favorited, while “foo/bar/” (and its subfolders) remain unchanged:

folders.foldername
foo/
foo/bar2/
foo/bar2/baz/

View it online: http://sqlfiddle.com/#!5/8a04e/14/0

EDIT: thanks to Christians answer pointing me to the EXCEPT operator, I was able to come up with the following modified version that also works for multiple favorites.

I’m very happy that it’s even possible at all to express this in pure SQL – I was briefly tempted to make it a hybrid SQL/node.js solution.

And of course, I’d happily accept any advice on possible optimizations!

Thanks.

Advertisement

Answer

This might not be the most efficient query, but it does the trick:

(Updated my original post)

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