运算符
ClickHouse 根据运算符的优先级、优先顺序和结合性,在查询解析阶段将其转换为相应的函数。
访问运算符
a[N]
– 访问数组元素。arrayElement(a, N)
函数。
a.N
– 访问元组元素。tupleElement(a, N)
函数。
数值取反运算符
-a
– negate (a)
函数。
对于元组取反:tupleNegate。
乘法和除法运算符
a * b
– multiply (a, b)
函数。
元组乘以数字:tupleMultiplyByNumber,标量积:dotProduct。
a / b
– divide(a, b)
函数。
元组除以数字:tupleDivideByNumber。
a % b
– modulo(a, b)
函数。
加法和减法运算符
a + b
– plus(a, b)
函数。
元组加法:tuplePlus。
a - b
– minus(a, b)
函数。
元组减法:tupleMinus。
比较运算符
equals 函数
a = b
– equals(a, b)
函数。
a == b
– equals(a, b)
函数。
notEquals 函数
a != b
– notEquals(a, b)
函数。
a <> b
– notEquals(a, b)
函数。
lessOrEquals 函数
a <= b
– lessOrEquals(a, b)
函数。
greaterOrEquals 函数
a >= b
– greaterOrEquals(a, b)
函数。
less 函数
a < b
– less(a, b)
函数。
greater 函数
a > b
– greater(a, b)
函数。
like 函数
a LIKE s
– like(a, b)
函数。
notLike 函数
a NOT LIKE s
– notLike(a, b)
函数。
ilike 函数
a ILIKE s
– ilike(a, b)
函数。
BETWEEN 函数
a BETWEEN b AND c
– 等同于 a >= b AND a <= c
。
a NOT BETWEEN b AND c
– 等同于 a < b OR a > c
。
用于处理数据集的运算符
in 函数
a IN ...
– in(a, b)
函数。
notIn 函数
a NOT IN ...
– notIn(a, b)
函数。
globalIn 函数
a GLOBAL IN ...
– globalIn(a, b)
函数。
globalNotIn 函数
a GLOBAL NOT IN ...
– globalNotIn(a, b)
函数。
in 子查询函数
a = ANY (subquery)
– in(a, subquery)
函数。
notIn 子查询函数
a != ANY (subquery)
– 等同于 a NOT IN (SELECT singleValueOrNull(*) FROM subquery)
。
in 子查询函数
a = ALL (subquery)
– 等同于 a IN (SELECT singleValueOrNull(*) FROM subquery)
。
notIn 子查询函数
a != ALL (subquery)
– notIn(a, subquery)
函数。
示例
使用 ALL 的查询
SELECT number AS a FROM numbers(10) WHERE a > ALL (SELECT number FROM numbers(3, 3));
结果
┌─a─┐
│ 6 │
│ 7 │
│ 8 │
│ 9 │
└───┘
使用 ANY 的查询
SELECT number AS a FROM numbers(10) WHERE a > ANY (SELECT number FROM numbers(3, 3));
结果
┌─a─┐
│ 4 │
│ 5 │
│ 6 │
│ 7 │
│ 8 │
│ 9 │
└───┘
用于处理日期和时间的运算符
EXTRACT
EXTRACT(part FROM date);
从给定的日期中提取部分。例如,您可以从给定的日期中检索月份,或从时间中检索秒数。
part
参数指定要检索日期的哪一部分。以下值可用
DAY
— 月份中的日期。可能的值:1–31。MONTH
— 月份的编号。可能的值:1–12。YEAR
— 年份。SECOND
— 秒。可能的值:0–59。MINUTE
— 分钟。可能的值:0–59。HOUR
— 小时。可能的值:0–23。
part
参数不区分大小写。
date
参数指定要处理的日期或时间。支持 Date 或 DateTime 类型。
示例
SELECT EXTRACT(DAY FROM toDate('2017-06-15'));
SELECT EXTRACT(MONTH FROM toDate('2017-06-15'));
SELECT EXTRACT(YEAR FROM toDate('2017-06-15'));
在以下示例中,我们创建一个表并向其中插入一个具有 DateTime
类型的值。
CREATE TABLE test.Orders
(
OrderId UInt64,
OrderName String,
OrderDate DateTime
)
ENGINE = Log;
INSERT INTO test.Orders VALUES (1, 'Jarlsberg Cheese', toDateTime('2008-10-11 13:23:44'));
SELECT
toYear(OrderDate) AS OrderYear,
toMonth(OrderDate) AS OrderMonth,
toDayOfMonth(OrderDate) AS OrderDay,
toHour(OrderDate) AS OrderHour,
toMinute(OrderDate) AS OrderMinute,
toSecond(OrderDate) AS OrderSecond
FROM test.Orders;
┌─OrderYear─┬─OrderMonth─┬─OrderDay─┬─OrderHour─┬─OrderMinute─┬─OrderSecond─┐
│ 2008 │ 10 │ 11 │ 13 │ 23 │ 44 │
└───────────┴────────────┴──────────┴───────────┴─────────────┴─────────────┘
您可以在 测试 中查看更多示例。
INTERVAL
创建一个 Interval 类型的值,该值应用于与 Date 和 DateTime 类型的值进行算术运算。
间隔类型
SECOND
MINUTE
HOUR
DAY
WEEK
MONTH
QUARTER
YEAR
设置 INTERVAL
值时,您还可以使用字符串文字。例如,INTERVAL 1 HOUR
等同于 INTERVAL '1 hour'
或 INTERVAL '1' hour
。
不同类型的间隔不能组合。您不能使用诸如 INTERVAL 4 DAY 1 HOUR
之类的表达式。请以小于或等于间隔最小单位的单位指定间隔,例如 INTERVAL 25 HOUR
。您可以使用连续操作,如下面的示例所示。
示例
SELECT now() AS current_date_time, current_date_time + INTERVAL 4 DAY + INTERVAL 3 HOUR;
┌───current_date_time─┬─plus(plus(now(), toIntervalDay(4)), toIntervalHour(3))─┐
│ 2020-11-03 22:09:50 │ 2020-11-08 01:09:50 │
└─────────────────────┴────────────────────────────────────────────────────────┘
SELECT now() AS current_date_time, current_date_time + INTERVAL '4 day' + INTERVAL '3 hour';
┌───current_date_time─┬─plus(plus(now(), toIntervalDay(4)), toIntervalHour(3))─┐
│ 2020-11-03 22:12:10 │ 2020-11-08 01:12:10 │
└─────────────────────┴────────────────────────────────────────────────────────┘
SELECT now() AS current_date_time, current_date_time + INTERVAL '4' day + INTERVAL '3' hour;
┌───current_date_time─┬─plus(plus(now(), toIntervalDay('4')), toIntervalHour('3'))─┐
│ 2020-11-03 22:33:19 │ 2020-11-08 01:33:19 │
└─────────────────────┴────────────────────────────────────────────────────────────┘
始终优先使用 INTERVAL
语法或 addDays
函数。简单的加法或减法(如 now() + ...
之类的语法)不考虑时间设置。例如,夏令时。
示例
SELECT toDateTime('2014-10-26 00:00:00', 'Asia/Istanbul') AS time, time + 60 * 60 * 24 AS time_plus_24_hours, time + toIntervalDay(1) AS time_plus_1_day;
┌────────────────time─┬──time_plus_24_hours─┬─────time_plus_1_day─┐
│ 2014-10-26 00:00:00 │ 2014-10-26 23:00:00 │ 2014-10-27 00:00:00 │
└─────────────────────┴─────────────────────┴─────────────────────┘
另请参阅
- Interval 数据类型
- toInterval 类型转换函数
逻辑 AND 运算符
语法 SELECT a AND b
— 使用函数 and 计算 a
和 b
的逻辑与。
逻辑 OR 运算符
语法 SELECT a OR b
— 使用函数 or 计算 a
和 b
的逻辑或。
逻辑非运算符
语法 SELECT NOT a
— 使用函数 not 计算 a
的逻辑非。
条件运算符
a ? b : c
– 等价于 if(a, b, c)
函数。
注意
条件运算符会计算 b 和 c 的值,然后检查条件 a 是否满足,并返回相应的值。如果 b
或 c
是 arrayJoin() 函数,则无论“a”条件如何,每行都会被复制。
条件表达式
CASE [x]
WHEN a THEN b
[WHEN ... THEN ...]
[ELSE c]
END
如果指定了 x
,则使用 transform(x, [a, ...], [b, ...], c)
函数。否则 – 使用 multiIf(a, b, ..., c)
。
如果表达式中没有 ELSE c
子句,则默认值为 NULL
。
transform
函数不适用于 NULL
。
连接运算符
s1 || s2
– 等价于 concat(s1, s2)
函数。
Lambda 创建运算符
x -> expr
– 等价于 lambda(x, expr)
函数。
以下运算符由于是括号,因此没有优先级
数组创建运算符
[x1, ...]
– 等价于 array(x1, ...)
函数。
元组创建运算符
(x1, x2, ...)
– 等价于 tuple(x2, x2, ...)
函数。
结合性
所有二元运算符都具有左结合性。例如,1 + 2 + 3
将转换为 plus(plus(1, 2), 3)
。有时这不会按预期工作。例如,SELECT 4 > 2 > 3
将得到 0。
为了提高效率,and
和 or
函数接受任意数量的参数。相应的 AND
和 OR
运算符链将转换为这些函数的单个调用。
检查 NULL
ClickHouse 支持 IS NULL
和 IS NOT NULL
运算符。
IS NULL
- 对于 Nullable 类型的值,
IS NULL
运算符将返回1
,如果值为NULL
。0
,否则。
- 对于其他值,
IS NULL
运算符始终返回0
。
可以通过启用 optimize_functions_to_subcolumns 设置进行优化。当 optimize_functions_to_subcolumns = 1
时,函数仅读取 null 子列,而不是读取和处理整个列数据。查询 SELECT n IS NULL FROM table
将转换为 SELECT n.null FROM TABLE
。
SELECT x+100 FROM t_null WHERE y IS NULL
┌─plus(x, 100)─┐
│ 101 │
└──────────────┘
IS NOT NULL
- 对于 Nullable 类型的值,
IS NOT NULL
运算符将返回0
,如果值为NULL
。1
,否则。
- 对于其他值,
IS NOT NULL
运算符始终返回1
。
SELECT * FROM t_null WHERE y IS NOT NULL
┌─x─┬─y─┐
│ 2 │ 3 │
└───┴───┘
可以通过启用 optimize_functions_to_subcolumns 设置进行优化。当 optimize_functions_to_subcolumns = 1
时,函数仅读取 null 子列,而不是读取和处理整个列数据。查询 SELECT n IS NOT NULL FROM table
将转换为 SELECT NOT n.null FROM TABLE
。