From 19e4352759200949d14ddda33918a54ab7a86a63 Mon Sep 17 00:00:00 2001 From: ogorbacheva Date: Mon, 22 Apr 2019 11:34:25 +0300 Subject: [PATCH] Doc fix: Actualize `ARRAY JOIN` (#5065) --- docs/en/query_language/select.md | 66 ++--- .../functions/array_functions.md | 2 +- docs/ru/query_language/select.md | 229 +++++++++--------- 3 files changed, 156 insertions(+), 141 deletions(-) diff --git a/docs/en/query_language/select.md b/docs/en/query_language/select.md index 458fa732f81..5e0877430b2 100644 --- a/docs/en/query_language/select.md +++ b/docs/en/query_language/select.md @@ -156,7 +156,7 @@ Here, a sample of 10% is taken from the second half of the data. ### ARRAY JOIN Clause {#select-array-join-clause} -Allows executing `JOIN` with an array or nested data structure. Allows you to perform `JOIN` both with the external array and with the inner array in the table. The intent is similar to the [arrayJoin](functions/array_functions.md#array_functions-join) function, but its functionality is broader. +Allows executing `JOIN` with an array or nested data structure. The intent is similar to the [arrayJoin](functions/array_join.md#functions_arrayjoin) function, but its functionality is broader. ``` sql SELECT @@ -168,14 +168,14 @@ FROM You can specify only a single `ARRAY JOIN` clause in a query. -When running the `ARRAY JOIN`, there is an optimization of the query execution order. Although the `ARRAY JOIN` must be always specified before the `WHERE/PREWHERE` clause, it can be performed as before the `WHERE/PREWHERE` (if its result is needed in this clause), as after completing it (to reduce the volume of calculations). The processing order is controlled by the query optimizer. +The query execution order is optimized when running `ARRAY JOIN`. Although `ARRAY JOIN` must always be specified before the `WHERE/PREWHERE` clause, it can be performed either before `WHERE/PREWHERE` (if the result is needed in this clause), or after completing it (to reduce the volume of calculations). The processing order is controlled by the query optimizer. Supported types of `ARRAY JOIN` are listed below: -- `ARRAY JOIN` - Executing `JOIN` with an array or nested data structure. Empty arrays are not included in the result. -- `LEFT ARRAY JOIN` - Unlike `ARRAY JOIN`, when using the `LEFT ARRAY JOIN` the result contains the rows with empty arrays. The value for an empty array is set to default value for an array element type (usually 0, empty string or NULL). +- `ARRAY JOIN` - In this case, empty arrays are not included in the result of `JOIN`. +- `LEFT ARRAY JOIN` - The result of `JOIN` contains rows with empty arrays. The value for an empty array is set to the default value for the array element type (usually 0, empty string or NULL). -Examples below demonstrate the usage of the `ARRAY JOIN` clause. Let's create a table with an [Array](../data_types/array.md) type column and insert values into it: +The examples below demonstrate the usage of the `ARRAY JOIN` and `LEFT ARRAY JOIN` clauses. Let's create a table with an [Array](../data_types/array.md) type column and insert values into it: ``` sql CREATE TABLE arrays_test @@ -195,7 +195,7 @@ VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', []); └─────────────┴─────────┘ ``` -The first example shows using the `ARRAY JOIN` clause: +The example below uses the `ARRAY JOIN` clause: ``` sql SELECT s, arr @@ -212,7 +212,7 @@ ARRAY JOIN arr; └───────┴─────┘ ``` -The second example shows using the `LEFT ARRAY JOIN` clause: +The next example uses the `LEFT ARRAY JOIN` clause: ``` sql SELECT s, arr @@ -230,7 +230,27 @@ LEFT ARRAY JOIN arr; └─────────────┴─────┘ ``` -The next example demonstrates using the `ARRAY JOIN` with the external array: +#### Using Aliases + +An alias can be specified for an array in the `ARRAY JOIN` clause. In this case, an array item can be accessed by this alias, but the array itself is accessed by the original name. Example: + +``` sql +SELECT s, arr, a +FROM arrays_test +ARRAY JOIN arr AS a; +``` + +``` +┌─s─────┬─arr─────┬─a─┐ +│ Hello │ [1,2] │ 1 │ +│ Hello │ [1,2] │ 2 │ +│ World │ [3,4,5] │ 3 │ +│ World │ [3,4,5] │ 4 │ +│ World │ [3,4,5] │ 5 │ +└───────┴─────────┴───┘ +``` + +Using aliases, you can perform `ARRAY JOIN` with an external array. For example: ``` sql SELECT s, arr_external @@ -252,27 +272,7 @@ ARRAY JOIN [1, 2, 3] AS arr_external; └─────────────┴──────────────┘ ``` -#### Using Aliases - -An alias can be specified for an array in the `ARRAY JOIN` clause. In this case, an array item can be accessed by this alias, but the array itself by the original name. Example: - -``` sql -SELECT s, arr, a -FROM arrays_test -ARRAY JOIN arr AS a; -``` - -``` -┌─s─────┬─arr─────┬─a─┐ -│ Hello │ [1,2] │ 1 │ -│ Hello │ [1,2] │ 2 │ -│ World │ [3,4,5] │ 3 │ -│ World │ [3,4,5] │ 4 │ -│ World │ [3,4,5] │ 5 │ -└───────┴─────────┴───┘ -``` - -Multiple arrays of the same size can be comma-separated in the `ARRAY JOIN` clause. In this case, `JOIN` is performed with them simultaneously (the direct sum, not the cartesian product). Example: +Multiple arrays can be comma-separated in the `ARRAY JOIN` clause. In this case, `JOIN` is performed with them simultaneously (the direct sum, not the cartesian product). Note that all the arrays must have the same size. Example: ``` sql SELECT s, arr, a, num, mapped @@ -290,6 +290,8 @@ ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(x -> x + 1, arr) AS ma └───────┴─────────┴───┴─────┴────────┘ ``` +The example below uses the [arrayEnumerate](functions/array_functions.md#array_functions-arrayenumerate) function: + ``` sql SELECT s, arr, a, num, arrayEnumerate(arr) FROM arrays_test @@ -308,7 +310,7 @@ ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num; #### ARRAY JOIN With Nested Data Structure -`ARRAY JOIN` also works with [nested data structure](../data_types/nested_data_structures/nested.md). Example: +`ARRAY `JOIN`` also works with [nested data structures](../data_types/nested_data_structures/nested.md). Example: ``` sql CREATE TABLE nested_test @@ -401,7 +403,7 @@ ARRAY JOIN nest AS n; └───────┴─────┴─────┴─────────┴────────────┘ ``` -The example of using the [arrayEnumerate](functions/array_functions.md#array_functions-arrayenumerate) function: +Example of using the [arrayEnumerate](functions/array_functions.md#array_functions-arrayenumerate) function: ``` sql SELECT s, `n.x`, `n.y`, `nest.x`, `nest.y`, num @@ -444,7 +446,7 @@ The table names can be specified instead of `` and ` +FROM +[LEFT] ARRAY JOIN +[WHERE|PREWHERE ] +... ``` -:) CREATE TABLE arrays_test (s String, arr Array(UInt8)) ENGINE = Memory +В запросе может быть указано не более одной секции `ARRAY JOIN`. + +При использовании `ARRAY JOIN`, порядок выполнения запроса оптимизируется. Несмотря на то что секция `ARRAY JOIN` всегда указывается перед выражением `WHERE / PREWHERE`, преобразование `JOIN` может быть выполнено как до выполнения выражения `WHERE / PREWHERE` (если результат необходим в этом выражении), так и после (чтобы уменьшить объем расчетов). Порядок обработки контролируется оптимизатором запросов. + +Секция `ARRAY JOIN` поддерживает следующие формы записи: + +- `ARRAY JOIN` — в этом случае результат `JOIN` не будет содержать пустые массивы; +- `LEFT ARRAY JOIN` — пустые массивы попадут в результат выполнения `JOIN`. В качестве значения для пустых массивов устанавливается значение по умолчанию. Обычно это 0, пустая строка или NULL, в зависимости от типа элементов массива. + +Рассмотрим примеры использования `ARRAY JOIN` и `LEFT ARRAY JOIN`. Для начала создадим таблицу, содержащую столбец с типом [Array](../data_types/array.md), и добавим в него значение: + +``` sql CREATE TABLE arrays_test ( s String, arr Array(UInt8) -) ENGINE = Memory +) ENGINE = Memory; -Ok. +INSERT INTO arrays_test +VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', []); +``` +``` +┌─s───────────┬─arr─────┐ +│ Hello │ [1,2] │ +│ World │ [3,4,5] │ +│ Goodbye │ [] │ +└─────────────┴─────────┘ +``` -0 rows in set. Elapsed: 0.001 sec. - -:) INSERT INTO arrays_test VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', []) - -INSERT INTO arrays_test VALUES - -Ok. - -3 rows in set. Elapsed: 0.001 sec. - -:) SELECT * FROM arrays_test - -SELECT * -FROM arrays_test - -┌─s───────┬─arr─────┐ -│ Hello │ [1,2] │ -│ World │ [3,4,5] │ -│ Goodbye │ [] │ -└─────────┴─────────┘ - -3 rows in set. Elapsed: 0.001 sec. - -:) SELECT s, arr FROM arrays_test ARRAY JOIN arr +В примере ниже используется `ARRAY JOIN`: +``` sql SELECT s, arr FROM arrays_test -ARRAY JOIN arr - +ARRAY JOIN arr; +``` +``` ┌─s─────┬─arr─┐ │ Hello │ 1 │ │ Hello │ 2 │ @@ -212,19 +215,37 @@ ARRAY JOIN arr │ World │ 4 │ │ World │ 5 │ └───────┴─────┘ - -5 rows in set. Elapsed: 0.001 sec. ``` -Для массива в секции ARRAY JOIN может быть указан алиас. В этом случае, элемент массива будет доступен под этим алиасом, а сам массив - под исходным именем. Пример: +Следующий пример использует `LEFT ARRAY JOIN`: +``` sql +SELECT s, arr +FROM arrays_test +LEFT ARRAY JOIN arr; ``` -:) SELECT s, arr, a FROM arrays_test ARRAY JOIN arr AS a +``` +┌─s───────────┬─arr─┐ +│ Hello │ 1 │ +│ Hello │ 2 │ +│ World │ 3 │ +│ World │ 4 │ +│ World │ 5 │ +│ Goodbye │ 0 │ +└─────────────┴─────┘ +``` +#### Использование алиасов + +Для массива в секции `ARRAY JOIN` может быть указан алиас. В этом случае, элемент массива будет доступен под этим алиасом, а сам массив — под исходным именем. Пример: + +``` sql SELECT s, arr, a FROM arrays_test -ARRAY JOIN arr AS a +ARRAY JOIN arr AS a; +``` +``` ┌─s─────┬─arr─────┬─a─┐ │ Hello │ [1,2] │ 1 │ │ Hello │ [1,2] │ 2 │ @@ -232,19 +253,39 @@ ARRAY JOIN arr AS a │ World │ [3,4,5] │ 4 │ │ World │ [3,4,5] │ 5 │ └───────┴─────────┴───┘ - -5 rows in set. Elapsed: 0.001 sec. ``` -В секции ARRAY JOIN может быть указано несколько массивов одинаковых размеров через запятую. В этом случае, JOIN делается с ними одновременно (прямая сумма, а не прямое произведение). Пример: +Используя алиасы, можно выполнять `JOIN` с внешними массивами: + +``` sql +SELECT s, arr_external +FROM arrays_test +ARRAY JOIN [1, 2, 3] AS arr_external; +``` ``` -:) SELECT s, arr, a, num, mapped FROM arrays_test ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(x -> x + 1, arr) AS mapped +┌─s───────────┬─arr_external─┐ +│ Hello │ 1 │ +│ Hello │ 2 │ +│ Hello │ 3 │ +│ World │ 1 │ +│ World │ 2 │ +│ World │ 3 │ +│ Goodbye │ 1 │ +│ Goodbye │ 2 │ +│ Goodbye │ 3 │ +└─────────────┴──────────────┘ +``` +В секции `ARRAY JOIN` можно указать через запятую сразу несколько массивов. В этом случае, `JOIN` делается с ними одновременно (прямая сумма, а не прямое произведение). Обратите внимание, массивы должны быть одинаковых размеров. Примеры: + +``` sql SELECT s, arr, a, num, mapped FROM arrays_test -ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(lambda(tuple(x), plus(x, 1)), arr) AS mapped +ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(x -> x + 1, arr) AS mapped; +``` +``` ┌─s─────┬─arr─────┬─a─┬─num─┬─mapped─┐ │ Hello │ [1,2] │ 1 │ 1 │ 2 │ │ Hello │ [1,2] │ 2 │ 2 │ 3 │ @@ -252,15 +293,17 @@ ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(lambda(tuple(x), plus( │ World │ [3,4,5] │ 4 │ 2 │ 5 │ │ World │ [3,4,5] │ 5 │ 3 │ 6 │ └───────┴─────────┴───┴─────┴────────┘ +``` -5 rows in set. Elapsed: 0.002 sec. - -:) SELECT s, arr, a, num, arrayEnumerate(arr) FROM arrays_test ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num +В примере ниже используется функция [arrayEnumerate](functions/array_functions.md#array_functions-arrayenumerate): +``` sql SELECT s, arr, a, num, arrayEnumerate(arr) FROM arrays_test -ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num +ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num; +``` +``` ┌─s─────┬─arr─────┬─a─┬─num─┬─arrayEnumerate(arr)─┐ │ Hello │ [1,2] │ 1 │ 1 │ [1,2] │ │ Hello │ [1,2] │ 2 │ 2 │ [1,2] │ @@ -268,54 +311,40 @@ ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num │ World │ [3,4,5] │ 4 │ 2 │ [1,2,3] │ │ World │ [3,4,5] │ 5 │ 3 │ [1,2,3] │ └───────┴─────────┴───┴─────┴─────────────────────┘ - -5 rows in set. Elapsed: 0.002 sec. ``` -ARRAY JOIN также работает с вложенными структурами данных. Пример: +#### ARRAY JOIN с вложенными структурами данных -``` -:) CREATE TABLE nested_test (s String, nest Nested(x UInt8, y UInt32)) ENGINE = Memory +`ARRAY JOIN` также работает с [вложенными структурами данных](../data_types/nested_data_structures/nested.md). Пример: +``` sql CREATE TABLE nested_test ( s String, nest Nested( x UInt8, y UInt32) -) ENGINE = Memory +) ENGINE = Memory; -Ok. - -0 rows in set. Elapsed: 0.006 sec. - -:) INSERT INTO nested_test VALUES ('Hello', [1,2], [10,20]), ('World', [3,4,5], [30,40,50]), ('Goodbye', [], []) - -INSERT INTO nested_test VALUES - -Ok. - -3 rows in set. Elapsed: 0.001 sec. - -:) SELECT * FROM nested_test - -SELECT * -FROM nested_test +INSERT INTO nested_test +VALUES ('Hello', [1,2], [10,20]), ('World', [3,4,5], [30,40,50]), ('Goodbye', [], []); +``` +``` ┌─s───────┬─nest.x──┬─nest.y─────┐ │ Hello │ [1,2] │ [10,20] │ │ World │ [3,4,5] │ [30,40,50] │ │ Goodbye │ [] │ [] │ └─────────┴─────────┴────────────┘ +``` -3 rows in set. Elapsed: 0.001 sec. - -:) SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest - +``` sql SELECT s, `nest.x`, `nest.y` FROM nested_test -ARRAY JOIN nest +ARRAY JOIN nest; +``` +``` ┌─s─────┬─nest.x─┬─nest.y─┐ │ Hello │ 1 │ 10 │ │ Hello │ 2 │ 20 │ @@ -323,19 +352,17 @@ ARRAY JOIN nest │ World │ 4 │ 40 │ │ World │ 5 │ 50 │ └───────┴────────┴────────┘ - -5 rows in set. Elapsed: 0.001 sec. ``` -При указании имени вложенной структуры данных в ARRAY JOIN, смысл такой же, как ARRAY JOIN со всеми элементами-массивами, из которых она состоит. Пример: - -``` -:) SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest.x, nest.y +При указании имени вложенной структуры данных в `ARRAY JOIN`, смысл такой же, как `ARRAY JOIN` со всеми элементами-массивами, из которых она состоит. Пример: +``` sql SELECT s, `nest.x`, `nest.y` FROM nested_test -ARRAY JOIN `nest.x`, `nest.y` +ARRAY JOIN `nest.x`, `nest.y`; +``` +``` ┌─s─────┬─nest.x─┬─nest.y─┐ │ Hello │ 1 │ 10 │ │ Hello │ 2 │ 20 │ @@ -343,19 +370,17 @@ ARRAY JOIN `nest.x`, `nest.y` │ World │ 4 │ 40 │ │ World │ 5 │ 50 │ └───────┴────────┴────────┘ - -5 rows in set. Elapsed: 0.001 sec. ``` Такой вариант тоже имеет смысл: -``` -:) SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest.x - +``` sql SELECT s, `nest.x`, `nest.y` FROM nested_test -ARRAY JOIN `nest.x` +ARRAY JOIN `nest.x`; +``` +``` ┌─s─────┬─nest.x─┬─nest.y─────┐ │ Hello │ 1 │ [10,20] │ │ Hello │ 2 │ [10,20] │ @@ -363,19 +388,17 @@ ARRAY JOIN `nest.x` │ World │ 4 │ [30,40,50] │ │ World │ 5 │ [30,40,50] │ └───────┴────────┴────────────┘ - -5 rows in set. Elapsed: 0.001 sec. ``` -Алиас для вложенной структуры данных можно использовать, чтобы выбрать как результат JOIN-а, так и исходный массив. Пример: - -``` -:) SELECT s, n.x, n.y, nest.x, nest.y FROM nested_test ARRAY JOIN nest AS n +Алиас для вложенной структуры данных можно использовать, чтобы выбрать как результат `JOIN`-а, так и исходный массив. Пример: +``` sql SELECT s, `n.x`, `n.y`, `nest.x`, `nest.y` FROM nested_test -ARRAY JOIN nest AS n +ARRAY JOIN nest AS n; +``` +``` ┌─s─────┬─n.x─┬─n.y─┬─nest.x──┬─nest.y─────┐ │ Hello │ 1 │ 10 │ [1,2] │ [10,20] │ │ Hello │ 2 │ 20 │ [1,2] │ [10,20] │ @@ -383,19 +406,17 @@ ARRAY JOIN nest AS n │ World │ 4 │ 40 │ [3,4,5] │ [30,40,50] │ │ World │ 5 │ 50 │ [3,4,5] │ [30,40,50] │ └───────┴─────┴─────┴─────────┴────────────┘ - -5 rows in set. Elapsed: 0.001 sec. ``` -Пример использования функции arrayEnumerate: - -``` -:) SELECT s, n.x, n.y, nest.x, nest.y, num FROM nested_test ARRAY JOIN nest AS n, arrayEnumerate(nest.x) AS num +Пример использования функции [arrayEnumerate](functions/array_functions.md#array_functions-arrayenumerate): +``` sql SELECT s, `n.x`, `n.y`, `nest.x`, `nest.y`, num FROM nested_test -ARRAY JOIN nest AS n, arrayEnumerate(`nest.x`) AS num +ARRAY JOIN nest AS n, arrayEnumerate(`nest.x`) AS num; +``` +``` ┌─s─────┬─n.x─┬─n.y─┬─nest.x──┬─nest.y─────┬─num─┐ │ Hello │ 1 │ 10 │ [1,2] │ [10,20] │ 1 │ │ Hello │ 2 │ 20 │ [1,2] │ [10,20] │ 2 │ @@ -403,16 +424,8 @@ ARRAY JOIN nest AS n, arrayEnumerate(`nest.x`) AS num │ World │ 4 │ 40 │ [3,4,5] │ [30,40,50] │ 2 │ │ World │ 5 │ 50 │ [3,4,5] │ [30,40,50] │ 3 │ └───────┴─────┴─────┴─────────┴────────────┴─────┘ - -5 rows in set. Elapsed: 0.002 sec. ``` -В запросе может быть указано не более одной секции ARRAY JOIN. - -Соответствующее преобразование может выполняться как до секции WHERE/PREWHERE (если его результат нужен в этой секции), так и после выполнения WHERE/PREWHERE (чтобы уменьшить объём вычислений). - - - ### Секция JOIN {#select-join} Соединяет данные в привычном для [SQL JOIN](https://en.wikipedia.org/wiki/Join_(SQL)) смысле.