The full_join()
method is similar to inner_join()
except that its output includes every
output of the left hand query at least once, and every output of the
right-hand query at least once. It's a wrapper for SQL's FULL
JOIN
.
For any queries l
, r
,
you can call l
.full_join(
r
,
condition
)
provided that:
condition
is an abstract_mapper<bool>
(in practice it will be a predicate
), and
l
's value type nor r
's
value type can be represented as all NULL
s (which
is unlikely to arise, but see here
for a discussion of which types allow all NULL
s).
l
and r
's value
mappers will both be visible
to condition
.
l
.full_join(
r
,
condition
)
returns a conditional_junction
with the following characteristics:
std::tuple<boost::optional<
Tl
>,
boost::optional<
Tr
>>
, where Tl
and Tr
are l
and r
's value types respectively.
tuple_mapper<boost::optional<
Tl
>,
boost::optional<
Tr
>>
, in which:
optional_mapper<
Tl
>
whose content mapper is
identical to l
's value mapper, and.
optional_mapper<
Tr
>
whose content mapper is
identical to r
's value mapper.
std::tuple
s formed from each combination
of the outputs of l
and r
,
for which condition
evaluates to
true
,
{
lo
,
boost::none}
, for each of l
's
outputs lo
that would not have made
an appearance otherwise, and.
{boost::none,
ro
}
, for each of r
's
outputs ro
that would not have made
an appearance otherwise.
const query<std::tuple<boost::optional<screen>, boost::optional<movie>>> nothing_left_behind = screens.full_join(movies, screens->current_movie_id == movies->id);