FULL OUTER JOIN
A full outer join will return unmatched and matched values from both tables.
For Example:
Let's use the job_history table and regions table. Refer Introduction to know about this table and the database.


In job_history, one records has a region_id, and one record doesn't have a region_id. So, one record doesn't have any matches with the regions table.
select * from regions full outer join job_history on regions.region_id = job_history.region_id;
Result:

Ecto query for full outer join
The join/5 function is used to perform a full outer join in Ecto. To learn more about the join/5 function, visit my JOIN page. Now let's use the :full option in join.
join/5
:full option in join
Expression
For Example:
HR.Region
|> join(:full, [r], c in HR.Country, on: r.region_id == c.region_id)
|> select([r, c], [r,c])
|> HR.Repo.all()
So the above query will return all matching and non-matching records in both tables.
|> join(:full, [r], c in HR.Country, on: r.region_id == c.region_id)
- It accepts the
HR.Regionschema as first argument. [r]is the reference variable for theHR.Regionschema. To understand reference variables, refer to Aliases in Ecto.c in HR.Countryis another schema with a reference variable.on: r.region_id == c.region_idis the condition.
Result:
iex(4)> HR.Region |> join(:full, [r], c in HR.Country, on: r.region_id == c.region_id) |> select([r, c], [r,c]) |> HR.Repo.all()
[
[
%HR.Region{
__meta__: #Ecto.Schema.Metadata<:loaded, "regions">,
region_id: 2,
region_name: "Americas"
},
%HR.Country{
__meta__: #Ecto.Schema.Metadata<:loaded, "countries">,
country_id: "AR",
country_name: "Argentina",
region_id: 2
}
],
[
%HR.Region{
__meta__: #Ecto.Schema.Metadata<:loaded, "regions">,
region_id: 3,
region_name: "Asia"
},
%HR.Country{
__meta__: #Ecto.Schema.Metadata<:loaded, "countries">,
country_id: "AU",
country_name: "Australia",
region_id: 3
}
],
[
%HR.Region{
__meta__: #Ecto.Schema.Metadata<:loaded, "regions">,
region_id: 1,
region_name: "Europe"
},
%HR.Country{
__meta__: #Ecto.Schema.Metadata<:loaded, "countries">,
country_id: "BE",
country_name: "Belgium",
region_id: 1
}
],
[
%HR.Region{
__meta__: #Ecto.Schema.Metadata<:loaded, "regions">,
region_id: 2,
region_name: "Americas"
},
%HR.Country{
__meta__: #Ecto.Schema.Metadata<:loaded, "countries">,
country_id: "BR",
country_name: "Brazil",
region_id: 2
}
],
[
%HR.Region{
__meta__: #Ecto.Schema.Metadata<:loaded, "regions">,
region_id: 5,
region_name: "India"
},
nil
],
[
%HR.Region{
__meta__: #Ecto.Schema.Metadata<:loaded, "regions">,
region_id: 6,
region_name: "China"
},
nil
],
[
%HR.Region{
__meta__: #Ecto.Schema.Metadata<:loaded, "regions">,
region_id: 7,
region_name: "Korean"
},
nil
]
]
Keywords
HR.Repo.all(from r in HR.Region, full_join: c in HR.Country, on: r.region_id == c.region_id, select: [r, c])