条件付き関数
if
条件分岐を実行します。
条件 cond
がゼロ以外の値に評価される場合、関数は式 then
の結果を返します。 cond
がゼロまたは NULL
に評価される場合は、else
式の結果が返されます。
設定 short_circuit_function_evaluation は、ショートサーキット評価が使用されるかどうかを制御します。 有効にすると、then
式は cond
が true
である行に対してのみ評価され、 else
式は cond
が false
である場合に評価されます。 たとえば、ショートサーキット評価を使用すると、クエリ SELECT if(number = 0, 0, intDiv(42, number)) FROM numbers(10)
を実行するときに、ゼロ除算の例外がスローされません。
then
とelse
は同様の型でなければなりません。
構文
エイリアス: cond ? then : else
(三項演算子)
引数
cond
– 評価される条件。 UInt8, Nullable(UInt8) または NULL。then
–condition
が真である場合に返される式。else
–condition
が偽であるかNULLである場合に返される式。
返される値
条件 cond
に応じて、then
またはelse
式のいずれかの結果。
例
結果:
multiIf
クエリ内でCASE演算子をよりコンパクトに記述できるようにします。
構文
設定 short_circuit_function_evaluation は、ショートサーキット評価が使用されるかどうかを制御します。 有効にすると、then_i
式は、((NOT cond_1) AND (NOT cond_2) AND ... AND (NOT cond_{i-1}) AND cond_i)
がtrue
である行に対してのみ評価され、cond_i
は、((NOT cond_1) AND (NOT cond_2) AND ... AND (NOT cond_{i-1}))
がtrue
である行に対してのみ評価されます。たとえば、ショートサーキット評価を使用すると、クエリ SELECT multiIf(number = 2, intDiv(1, number), number = 5) FROM numbers(10)
を実行するときに、ゼロ除算の例外が発生しません。
引数
関数は 2N+1
のパラメータを受け付けます:
cond_N
—then_N
が返されるべきかを制御するN番目の評価された条件。then_N
—cond_N
が真である場合の関数の結果。else
— どの条件も真でない場合の関数の結果。
返される値
条件 cond_N
に応じて、then_N
またはelse
の式のいずれかの結果。
例
次のテーブルを考えます。
条件結果を直接使用
条件は常に 0
、1
または NULL
になります。したがって、次のように条件結果を直接使用できます。
NULL値に関する条件
条件に NULL
値が関与すると、結果も NULL
になります。
したがって、タイプが Nullable
の場合は、クエリを慎重に構築する必要があります。
次の例は、multiIf
に等しい条件を追加できずに失敗することでこれを示しています。
greatest
値のリストの中で最大のものを返します。 リストのすべてのメンバーは互換性のある型でなければなりません。
例:
返される型はFloat64であり、UInt8は比較のために64ビットに昇格する必要があります。
返される型はDateTime64であり、DateTime32は比較のために64ビットに昇格する必要があります。
least
値のリストの中で最小のものを返します。 リストのすべてのメンバーは互換性のある型でなければなりません。
例:
返される型はFloat64であり、UInt8は比較のために64ビットに昇格する必要があります。
返される型はDateTime64であり、DateTime32は比較のために64ビットに昇格する必要があります。
clamp
戻り値をAとBの間に制約します。
構文
引数
value
– 入力値。min
– 下限を制限します。max
– 上限を制限します。
返される値
値が最小値より小さい場合、最小値を返します。最大値より大きい場合は、最大値を返します。それ以外の場合は、現在の値を返します。
例:
CASE文
ClickHouseのCASE式は、SQLのCASE演算子に類似した条件ロジックを提供します。条件を評価し、最初に一致した条件に基づいて値を返します。
ClickHouseは2つの形式のCASEをサポートしています。
CASE WHEN ... THEN ... ELSE ... END
この形式は完全な柔軟性を提供し、内部的にはmultiIf関数を使用して実装されています。各条件は独立して評価され、式は非定数の値を含むことができます。
CASE <expr> WHEN <val1> THEN ... WHEN <val2> THEN ... ELSE ... END
このよりコンパクトな形式は、定数値の一致の最適化を行い、内部的に caseWithExpression()
を使用します。
たとえば、次のように記述できます。
この形式では、返す式が定数である必要はありません。
注意点
ClickHouseは、CASE式(またはその内部相当物、たとえば multiIf
)の結果型を、条件を評価する前に決定します。これは、返す式が異なる型、たとえば異なるタイムゾーンや数値型である場合に重要です。
- 結果型は、すべてのブランチの中で最大の互換性のある型に基づいて選択されます。
- この型が選択されると、他のすべてのブランチは暗黙的にこの型にキャストされます - 実行時にそのロジックが実行されない場合でも。
- DateTime64のような型では、タイムゾーンが型シグネチャの一部であるため、驚くべき動作を引き起こす可能性があります:最初に遭遇したタイムゾーンがすべてのブランチに使用される場合があります、他のブランチが異なるタイムゾーンを指定している場合であっても。
たとえば、以下ではすべての行が最初に一致したブランチのタイムスタンプを返します。つまり、Asia/Kolkata
です。
ここで、ClickHouseは複数の DateTime64(3, <timezone>)
の返り値の型を見ます。最初に見るものを基に共通の型を推論し、他のブランチを暗黙的にこの型にキャストします。
これは、意図したタイムゾーンのフォーマットを保持するために文字列に変換することで対処できます。