ARRAY JOIN 句が行う処理の基本的なケースです。
この名前は、配列またはネストされたデータ構造に対して JOIN を実行するものと見なせることに由来します。意図としては arrayJoin 関数に似ていますが、句の機能のほうがより広範です。
構文:
ARRAY JOIN の種類は以下のとおりです。
ARRAY JOIN- 基本的なケースでは、空の配列はJOINの結果に含まれません。LEFT ARRAY JOIN-JOINの結果には、空の配列を持つ行が含まれます。空の配列の値には、配列の要素型のデフォルト値 (通常は 0、空文字列、または NULL) が設定されます。
ARRAY JOIN の基本的な例
ARRAY JOIN と LEFT ARRAY JOIN
ARRAY JOIN 句と LEFT ARRAY JOIN 句の使用方法を示します。Array 型のカラムを持つテーブルを作成し、値を挿入してみましょう。
ARRAY JOIN句を使用します。
LEFT ARRAY JOIN 句を使用します。
ARRAY JOIN と arrayEnumerate 関数
ARRAY JOIN と組み合わせて使用されます。ARRAY JOIN を適用した後、各配列に対して対象を1回だけカウントできるようになります。例:
ARRAY JOIN を適用した後の文字列数) 、Hits はページビュー数 (ARRAY JOIN を適用する前の文字列数) を表します。このケースでは、もっと簡単な方法で同じ結果を得ることができます。
ARRAY JOIN と arrayEnumerateUniq
ARRAY JOIN を使用して配列要素を集計する場合に便利です。
この例では、各 goal ID について、コンバージョン数 (ネストされた Goals データ構造の各要素は到達した goal を表し、これをコンバージョンと呼びます) と session 数を計算しています。ARRAY JOIN がなければ、session 数は sum(Sign) として数えられます。しかし、このケースでは行がネストされた Goals 構造によって増やされているため、その後に各 session を 1 回だけ数えるには、arrayEnumerateUniq(Goals.ID) 関数の値に条件を適用します。
別名の使用
ARRAY JOIN句では、配列に別名を指定できます。この場合、配列の要素にはその別名でアクセスできますが、配列自体には元の名前でアクセスします。例:
ARRAY JOIN を実行できます。たとえば:
ARRAY JOIN 句内でカンマ区切りで指定できます。この場合、それらに対して JOIN が同時に実行されます (デカルト積ではなく、直和です) 。なお、デフォルトではすべての配列のサイズが同じである必要があります。例:
SETTINGS enable_unaligned_array_join = 1 を使用すると結合できます。例:
ネストされたデータ構造での ARRAY JOIN
ARRAY JOIN は、ネストされたデータ構造でも使用できます。
ARRAY JOIN でネストされたデータ構造の名前を指定した場合、その意味は、そのデータ構造を構成するすべての配列要素に対して ARRAY JOIN を適用するのと同じです。以下に例を示します。
JOIN の結果とソース配列のどちらを選択するかを指定するために別名を使用できます。例:
実装の詳細
ARRAY JOIN の実行時には、クエリの実行順序が最適化されます。ARRAY JOIN はクエリ内で常に WHERE/PREWHERE 句より前に指定する必要がありますが、ARRAY JOIN の結果をフィルタリングに使用しない限り、技術的にはこれらはどの順序でも実行できます。処理順序はクエリオプティマイザによって制御されます。
短絡関数評価との非互換性
if、multiIf、and、or などの特定の関数における複雑な式の実行を最適化する機能です。これにより、これらの関数の実行中に、0 による除算のような例外が発生するのを防げます。
arrayJoin は常に実行されるため、短絡関数評価には対応していません。これは、arrayJoin がクエリ分析および実行時に、ほかの関数とは別に処理される特殊な関数であり、短絡関数評価では機能しない追加ロジックを必要とするためです。結果の行数は arrayJoin の結果に依存するため、arrayJoin の遅延実行を実装するのは複雑すぎるうえ、コストも高くなります。