For any query q
, exists(
q
)
builds and returns a predicate
that, when executed, tests whether q
produces
any output. So it's a wrapper of SQL's keyword EXISTS
.
q
is allowed
to use mappers from the enclosing context. As the
PostgreSQL documentation explains:
The subquery can refer to variables from the surrounding query, which will act as constants during any one evaluation of the subquery.
I find that the most useful cases tend to take advantage of that; e.g.:
const query<movie> hall_of_fame = movies .where(exists(critics.where(critics->favorite_movie == movies->id)));
The query critics.where(critics->favorite_movie ==
movies->id)
is
not one you could execute by itself, because movies->id
is not visible without the
context provided by movies.where(
...)
.
Personally I prefer to break the code up as follows:
query<critic> fans_of(const exprn_mapper<serial> &movie_id) { return critics.where(critics->favorite_movie == movie_id); } const query<movie> hall_of_fame = movies.where(exists(fans_of(movies->id)));
The benefits are: