content/shared/sql-reference/join.md
Use the JOIN clause to join data from different tables together based on
logical relationships.
SELECT_clause
FROM <left_join_items>
[INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER]] JOIN <right_join_items>
ON <join_condition>
[WHERE_clause]
[GROUP_BY_clause]
[HAVING_clause]
[ORDER_BY_clause]
FROM clause that
represent the left side of the join.JOIN clause that
represent the right side of the join.ON clause that uses the
= (equal to) comparison operator to compare column values from the left side
of the join to column values on the right side of the join. Rows with values
that match the defined predicate are joined using the specified
join type.[!Note] If both sides of the join include columns with the same name, you need to use the fully-qualified reference to prevent ambiguity. A fully-qualified reference uses dot notation to reference both the table name and the column name--for example:
table_name.column_name
The following joins types are supported:
{{< flex >}}
{{< flex-content "quarter" >}}
<a href="#inner-join">
<p style="text-align:center"><strong>INNER JOIN</strong></p>
{{< svg svg="static/svgs/join-diagram.svg" class="inner small center" >}}
</a>
{{< /flex-content >}}
{{< flex-content "quarter" >}}
<a href="#left-outer-join">
<p style="text-align:center"><strong>LEFT [OUTER] JOIN</strong></p>
{{< svg svg="static/svgs/join-diagram.svg" class="left small center" >}}
</a>
{{< /flex-content >}}
{{< flex-content "quarter" >}}
<a href="#right-outer-join">
<p style="text-align:center"><strong>RIGHT [OUTER] JOIN</strong></p>
{{< svg svg="static/svgs/join-diagram.svg" class="right small center" >}}
</a>
{{< /flex-content >}}
{{< flex-content "quarter" >}}
<a href="#full-outer-join">
<p style="text-align:center"><strong>FULL [OUTER] JOIN</strong></p>
{{< svg svg="static/svgs/join-diagram.svg" class="full small center" >}}
</a>
{{< /flex-content >}}
{{< /flex >}}
The examples below illustrate join methods using the following tables:
{{% influxdb/custom-timestamps %}}
| time | station | produced |
|---|---|---|
| 2022-01-01T08:00:00Z | B1 | 26 |
| 2022-01-01T09:00:00Z | B1 | 54 |
| 2022-01-01T10:00:00Z | B1 | 56 |
| 2022-01-01T11:00:00Z | B1 | |
| 2022-01-01T12:00:00Z | B1 | 82 |
| time | station | level | message |
|---|---|---|---|
| 2022-01-01T10:00:00Z | B1 | warn | Maintenance required |
| 2022-01-01T11:00:00Z | B1 | crit | Station offline |
{{% /influxdb/custom-timestamps %}}
Inner joins combine rows from tables on the left and right side of the join
based on common column values defined in the ON clause. Rows that don't have
matching column values are not included in the output table.
{{% influxdb/custom-timestamps %}}
{{% caption %}}View sample tables{{% /caption %}}
SELECT
*
FROM
prod_line
RIGHT JOIN errors ON
prod_line.time = errors.time
AND prod_line.station = errors.station
ORDER BY
prod_line.time
| time | station | produced | time | station | level | message |
|---|---|---|---|---|---|---|
| 2022-01-01T10:00:00Z | B1 | 56 | 2022-01-01T10:00:00Z | B1 | warn | Maintenance required |
| 2022-01-01T11:00:00Z | B1 | 2022-01-01T11:00:00Z | B1 | crit | Station offline |
{{% /influxdb/custom-timestamps %}}
A left outer join returns all rows from the left side of the join and only
returns data from the right side of the join in rows with matching column values
defined in the ON clause.
{{% influxdb/custom-timestamps %}}
{{% caption %}}View sample tables{{% /caption %}}
SELECT
*
FROM
prod_line
LEFT JOIN errors ON
prod_line.time = errors.time
AND prod_line.station = errors.station
ORDER BY
prod_line.time
| time | station | produced | time | station | level | message |
|---|---|---|---|---|---|---|
| 2022-01-01T08:00:00Z | B1 | 26 | ||||
| 2022-01-01T09:00:00Z | B1 | 54 | ||||
| 2022-01-01T10:00:00Z | B1 | 56 | 2022-01-01T10:00:00Z | B1 | warn | Maintenance required |
| 2022-01-01T11:00:00Z | B1 | 2022-01-01T11:00:00Z | B1 | crit | Station offline | |
| 2022-01-01T12:00:00Z | B1 | 82 |
{{% /influxdb/custom-timestamps %}}
A right outer join returns all rows from the right side of the join and only
returns data from the left side of the join in rows with matching column values
defined in the ON clause.
{{% influxdb/custom-timestamps %}}
{{% caption %}}View sample tables{{% /caption %}}
SELECT
*
FROM
prod_line
RIGHT JOIN errors ON
prod_line.time = errors.time
AND prod_line.station = errors.station
ORDER BY
prod_line.time
| time | station | produced | time | station | level | message |
|---|---|---|---|---|---|---|
| 2022-01-01T10:00:00Z | B1 | 56 | 2022-01-01T10:00:00Z | B1 | warn | Maintenance required |
| 2022-01-01T11:00:00Z | B1 | 2022-01-01T11:00:00Z | B1 | crit | Station offline |
{{% /influxdb/custom-timestamps %}}
A full outer join returns all data from the left and right sides of the join and
combines rows with matching column values defined in the ON clause.
Data that is not available on each respective side of the join is NULL.
{{% influxdb/custom-timestamps %}}
{{% caption %}}View sample tables{{% /caption %}}
SELECT
*
FROM
prod_line
FULL JOIN errors ON
prod_line.time = errors.time
AND prod_line.station = errors.station
ORDER BY
time
| time | station | produced | time | station | level | message |
|---|---|---|---|---|---|---|
| 2022-01-01T08:00:00Z | B1 | 26 | ||||
| 2022-01-01T09:00:00Z | B1 | 54 | ||||
| 2022-01-01T10:00:00Z | B1 | 56 | 2022-01-01T10:00:00Z | B1 | warn | Maintenance required |
| 2022-01-01T11:00:00Z | B1 | 2022-01-01T11:00:00Z | B1 | crit | Station offline | |
| 2022-01-01T12:00:00Z | B1 | 82 |
{{% /influxdb/custom-timestamps %}}
If a column exists on both sides of the join and is used in the SELECT,
ON, WHERE, HAVING, GROUP BY, or ORDER BY clause, you must use a
fully-qualified reference. For example, if both
sides of the join have a time column and you want to explicitly select a
time column, you must specifiy which side of the join to use the time column from:
{{% code-callout "prod_line.time" "green" %}}
SELECT
prod_line.time,
produced,
message,
FROM
prod_line
INNER JOIN errors ON
-- ...
{{% /code-callout %}}