2020-04-03 13:23:32 +00:00
---
toc_priority: 40
toc_title: Join
---
2020-06-10 20:14:00 +00:00
# Join Table Engine {#join}
2017-04-03 19:49:50 +00:00
2020-06-10 20:14:00 +00:00
Optional prepared data structure for usage in [JOIN ](../../../sql-reference/statements/select/join.md#select-join ) operations.
!!! note "Note"
This is not an article about the [JOIN clause ](../../../sql-reference/statements/select/join.md#select-join ) itself.
2019-06-21 07:58:15 +00:00
2020-03-18 18:43:51 +00:00
## Creating a Table {#creating-a-table}
2017-06-13 20:35:07 +00:00
2020-03-20 10:10:48 +00:00
``` sql
2019-06-21 07:58:15 +00:00
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],
) ENGINE = Join(join_strictness, join_type, k1[, k2, ...])
```
2020-04-30 18:19:18 +00:00
See the detailed description of the [CREATE TABLE ](../../../sql-reference/statements/create.md#create-table-query ) query.
2019-06-21 07:58:15 +00:00
**Engine Parameters**
2020-05-15 04:34:54 +00:00
- `join_strictness` – [JOIN strictness ](../../../sql-reference/statements/select/join.md#select-join-strictness ).
- `join_type` – [JOIN type ](../../../sql-reference/statements/select/join.md#select-join-types ).
2020-03-21 04:11:51 +00:00
- `k1[, k2, ...]` – Key columns from the `USING` clause that the `JOIN` operation is made with.
2019-06-21 07:58:15 +00:00
2020-03-20 10:10:48 +00:00
Enter `join_strictness` and `join_type` parameters without quotes, for example, `Join(ANY, LEFT, col1)` . They must match the `JOIN` operation that the table will be used for. If the parameters don’ t match, ClickHouse doesn’ t throw an exception and may return incorrect data.
2019-06-21 07:58:15 +00:00
2020-03-20 10:10:48 +00:00
## Table Usage {#table-usage}
2019-06-21 07:58:15 +00:00
2020-03-20 10:10:48 +00:00
### Example {#example}
2019-06-21 07:58:15 +00:00
Creating the left-side table:
2020-03-20 10:10:48 +00:00
``` sql
2019-07-31 14:49:16 +00:00
CREATE TABLE id_val(`id` UInt32, `val` UInt32) ENGINE = TinyLog
```
2020-03-20 10:10:48 +00:00
``` sql
2019-07-31 14:49:16 +00:00
INSERT INTO id_val VALUES (1,11)(2,12)(3,13)
2017-12-28 15:13:23 +00:00
```
2017-06-13 04:15:47 +00:00
2019-06-21 07:58:15 +00:00
Creating the right-side `Join` table:
2017-04-03 19:49:50 +00:00
2020-03-20 10:10:48 +00:00
``` sql
2019-07-31 14:49:16 +00:00
CREATE TABLE id_val_join(`id` UInt32, `val` UInt8) ENGINE = Join(ANY, LEFT, id)
```
2020-03-20 10:10:48 +00:00
``` sql
2019-06-21 07:58:15 +00:00
INSERT INTO id_val_join VALUES (1,21)(1,22)(3,23)
```
2017-04-03 19:49:50 +00:00
2019-06-21 07:58:15 +00:00
Joining the tables:
2019-05-27 19:34:04 +00:00
2020-03-20 10:10:48 +00:00
``` sql
2019-06-21 07:58:15 +00:00
SELECT * FROM id_val ANY LEFT JOIN id_val_join USING (id) SETTINGS join_use_nulls = 1
```
2020-03-20 10:10:48 +00:00
``` text
2019-06-21 07:58:15 +00:00
┌─id─┬─val─┬─id_val_join.val─┐
│ 1 │ 11 │ 21 │
│ 2 │ 12 │ ᴺᵁᴸᴸ │
│ 3 │ 13 │ 23 │
└────┴─────┴─────────────────┘
```
2017-04-03 19:49:50 +00:00
2019-07-31 14:49:16 +00:00
As an alternative, you can retrieve data from the `Join` table, specifying the join key value:
2017-12-28 15:13:23 +00:00
2020-03-20 10:10:48 +00:00
``` sql
2019-06-21 07:58:15 +00:00
SELECT joinGet('id_val_join', 'val', toUInt32(1))
2019-05-27 19:34:04 +00:00
```
2020-03-20 10:10:48 +00:00
``` text
2019-06-21 07:58:15 +00:00
┌─joinGet('id_val_join', 'val', toUInt32(1))─┐
│ 21 │
└────────────────────────────────────────────┘
2019-05-27 19:34:04 +00:00
```
2020-03-20 10:10:48 +00:00
### Selecting and Inserting Data {#selecting-and-inserting-data}
2019-06-21 07:58:15 +00:00
2019-07-31 14:49:16 +00:00
You can use `INSERT` queries to add data to the `Join` -engine tables. If the table was created with the `ANY` strictness, data for duplicate keys are ignored. With the `ALL` strictness, all rows are added.
2019-06-21 07:58:15 +00:00
2019-07-31 14:49:16 +00:00
You cannot perform a `SELECT` query directly from the table. Instead, use one of the following methods:
2019-06-21 07:58:15 +00:00
2020-03-21 04:11:51 +00:00
- Place the table to the right side in a `JOIN` clause.
2020-04-30 18:19:18 +00:00
- Call the [joinGet ](../../../sql-reference/functions/other-functions.md#joinget ) function, which lets you extract data from the table the same way as from a dictionary.
2019-06-21 07:58:15 +00:00
2020-03-18 18:43:51 +00:00
### Limitations and Settings {#join-limitations-and-settings}
2019-06-21 07:58:15 +00:00
When creating a table, the following settings are applied:
2019-06-18 09:57:42 +00:00
2020-04-03 13:23:32 +00:00
- [join\_use\_nulls ](../../../operations/settings/settings.md#join_use_nulls )
2020-04-30 18:19:18 +00:00
- [max\_rows\_in\_join ](../../../operations/settings/query-complexity.md#settings-max_rows_in_join )
- [max\_bytes\_in\_join ](../../../operations/settings/query-complexity.md#settings-max_bytes_in_join )
- [join\_overflow\_mode ](../../../operations/settings/query-complexity.md#settings-join_overflow_mode )
2020-04-03 13:23:32 +00:00
- [join\_any\_take\_last\_row ](../../../operations/settings/settings.md#settings-join_any_take_last_row )
2019-05-27 19:34:04 +00:00
2020-03-20 10:10:48 +00:00
The `Join` -engine tables can’ t be used in `GLOBAL JOIN` operations.
2019-06-21 07:58:15 +00:00
2020-05-15 04:34:54 +00:00
The `Join` -engine allows use [join\_use\_nulls ](../../../operations/settings/settings.md#join_use_nulls ) setting in the `CREATE TABLE` statement. And [SELECT ](../../../sql-reference/statements/select/index.md ) query allows use `join_use_nulls` too. If you have different `join_use_nulls` settings, you can get an error joining table. It depends on kind of JOIN. When you use [joinGet ](../../../sql-reference/functions/other-functions.md#joinget ) function, you have to use the same `join_use_nulls` setting in `CRATE TABLE` and `SELECT` statements.
2020-01-24 13:59:33 +00:00
2020-03-20 10:10:48 +00:00
## Data Storage {#data-storage}
2019-06-21 07:58:15 +00:00
2019-07-31 14:49:16 +00:00
`Join` table data is always located in the RAM. When inserting rows into a table, ClickHouse writes data blocks to the directory on the disk so that they can be restored when the server restarts.
2019-06-21 07:58:15 +00:00
2019-07-31 14:49:16 +00:00
If the server restarts incorrectly, the data block on the disk might get lost or damaged. In this case, you may need to manually delete the file with damaged data.
2018-10-16 10:47:17 +00:00
2020-01-30 10:34:55 +00:00
[Original article ](https://clickhouse.tech/docs/en/operations/table_engines/join/ ) <!--hide-->