ClickHouse 14.常用操作符介绍


1. 介绍 ClickHouse 的操作符

所有的操作符(运算符)都会在查询时,依据他们的优先级及其结合顺序,在被解析时转换为对应的函数。
下面按优先级从高到低列出各组运算符及其对应的函数:

2. 下标运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- 数组中的下标运算符
-- a[N] – 数组中的第N个元素
-- 对应函数 arrayElement(a, N)
select array(1,2,3) as a, a[1] as a1,arrayElement(a, 1) as func_a1;
┌─a───────┬─a1─┬─func_a1─┐
│ [1,2,3] │ 11
└─────────┴────┴─────────┘

-- 元组中的下标运算符
-- a.N – 元组中第N个元素
-- 对应函数 tupleElement(a, N)
select tuple(1,'a') as a, a.1 as a1,tupleElement(a, 2) as func_a1
┌─a───────┬─a1─┬─func_a1─┐
│ (1,'a') │ 1 │ a │
└─────────┴────┴─────────┘

3. 负号

1
2
3
4
5
6
-- 负号 -a
-- 对应函数 negate(a)
select -(-3) as n1,negate(n1) as n2;
┌─n1─┬─n2─┐
3-3
└────┴────┘

4. 乘、除、取余、加、减、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
-- 乘号 '*'
-- 对应函数 multiply(a, b)

select 5 * 5 as n1,multiply(n1, 5) as n2;
┌─n1─┬──n2─┐
25125
└────┴─────┘

-- 除号 '/'
-- 对应函数 divide(a, b)
select 5 / 5 as n1,divide(n1, 5) as n2;
┌─n1─┬──n2─┐
10.2
└────┴─────┘

-- 取余 '%'
-- 对应函数 modulo(a, b)
select 8 % 5 as n1, modulo(n1, 2) as n2;
┌─n1─┬─n2─┐
31
└────┴────┘

-- 加号 '+'
-- 对应函数 plus(a, b)
select 5 + 5 as n1, plus(n1, 5) as n2;
┌─n1─┬─n2─┐
1015
└────┴────┘

-- 减号 '-'
-- 对应函数 minus(a, b)
select 10 - 5 as n1, minus(n1, 5) as n2;
┌─n1─┬─n2─┐
50
└────┴────┘

5. 关系运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
-- 相等 '=' ,'=='
-- 对应函数 equals(a, b)
select 'a' = 'b' as n1,'a' == 'b' as n2, equals('a','a') as n3,toTypeName(n1) as type;
┌─n1─┬─n2─┬─n3─┬─type──┐
001 │ UInt8 │
└────┴────┴────┴───────┘

-- 不等 '!=','<>'
-- 对应函数 notEquals(a, b)
select 'a' != 'b' as n1,'a' <> 'b' as n2, notEquals('a','a') as n3,toTypeName(n1) as type;
┌─n1─┬─n2─┬─n3─┬─type──┐
110 │ UInt8 │
└────┴────┴────┴───────┘

-- 小于等于 '<=',''
-- 对应函数 lessOrEquals(a, b)
select 'a' <= 'b' as n1, lessOrEquals('a','a') as n2,toTypeName(n1) as type;
┌─n1─┬─n2─┬─type──┐
11 │ UInt8 │
└────┴────┴───────┘

-- 大于等于 '>='
-- 对应函数 greaterOrEquals(a, b)
select 'a' >= 'b' as n1, lessOrEquals('a','a') as n2,toTypeName(n1) as type;

-- 小于(如果前者小于后者,则返回1;否则返回0)
-- 对应函数 less(a, b)
select 'a' < 'b' as n1, less('a','a') as n2,toTypeName(n1) as type;
┌─n1─┬─n2─┬─type──┐
10 │ UInt8 │
└────┴────┴───────┘

-- 大于(如果前者大于后者,则返回1;否则返回0)
-- 对应函数 greater(a, b)
select 'a' > 'b' as n1, greater('a','a') as n2,toTypeName(n1) as type;
┌─n1─┬─n2─┬─type──┐
00 │ UInt8 │
└────┴────┴───────┘

-- 相似 'like'
-- 对应函数 like(a, b)
select 's1' like 's2' as n1, like('s1','s1') as n2;
┌─n1─┬─n2─┐
01
└────┴────┘

-- 不相似 'NOT LIKE'
-- 对应函数 notLike(a, b)
select 's1' not like 's2' as n1, notLike('s1','s1') as n2;
┌─n1─┬─n2─┐
10
└────┴────┘

-- 区间 'a BETWEEN b AND c'
-- 等价与 a >= b AND a <= c
SELECT
('b' >= 'a') AND ('b' <= 'c') AS n1,
('b' <= 'a') AND ('b' >= 'c') AS n2;

┌─n1─┬─n2─┐
10
└────┴────┘

6. 集合关系运算符

1
2
3
4
a IN ... – 对应函数 in(a, b)
a NOT IN ... – 对应函数 notIn(a, b)
a GLOBAL IN ... – 对应函数 globalIn(a, b)
a GLOBAL NOT IN ... – 对应函数 globalNotIn(a, b)

7. 逻辑非或非

1
2
3
4
5
6
7
8
9
10
11
12
13
-- 逻辑与 'and'
-- 对应函数and(a, b)
select 'a'='a' and 'b'='b' as n1,and('a'='b','b'='c') as n2;
┌─n1─┬─n2─┐
10
└────┴────┘

-- 逻辑或
-- 对应函数 or(a, b)
select 'a'='a' or 'b'='b' as n1,or('a'='b','c'='c') as n2;
┌─n1─┬─n2─┐
11
└────┴────┘

8. 条件运算符

  • 条件运算符会先计算表达式b和表达式c的值,再根据表达式a的真假,返回相应的值。

  • 如果表达式b和表达式c是 arrayJoin() 函数,则不管表达式a是真是假,每行都会被复制展开。

1
2
3
4
5
6
-- 条件运算符 a ? b : c
-- 对应函数 if(a, b, c)
select 1 < 2 ? 'yes' : 'no' as s1, if(1 > 2 ,'no','yes') as s2;
┌─s1──┬─s2──┐
│ yes │ yes │
└─────┴─────┘

9. 日期时间运算符

9.1. EXTRACT

1
2
3
4
5
6
7
8
9
10
11
12
13
-- 时间提取 ,从指定时间中提取某一部分
-- 从给定日期中提取部件。 例如,您可以从给定日期检索一个月,或从时间检索一秒钟。
EXTRACT(part FROM date);

-- date 参数指定要处理的日期或时间。 无论是 日期 或 日期时间 支持类型。
-- part 指定要检索的日期部分,参数不区分大小写。一下为 part 支持类型
YEAR — 获取年
QUARTER - 获取季度,1(一季度:1-3),2(二季度:4-6),3(三季度:7-9),4(四季度:10-12
MONTH — 获取月份 112.
DAY — 获取日 131.
HOUR — 获取小时 023.
MINUTE — 获取分钟 059.
SECOND — 获取秒钟 059.
  • 使用示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
-- 获取年 EXTRACT(YEAR FROM date)
-- 对应函数 toYear(date)
SELECT toDate('2021-08-05 21:50:25') as dt , EXTRACT(YEAR FROM dt) as d1,toYear(dt) as d2;
┌─────────dt─┬───d1─┬───d2─┐
2021-08-0520212021
└────────────┴──────┴──────┘

-- 获取季度 EXTRACT(QUARTER FROM date)
-- 对应函数 toQuarter(date)
SELECT toDate('2021-08-05 21:50:25') as dt , EXTRACT(QUARTER FROM dt) as d1, toQuarter(dt) as d2;
┌─────────dt─┬─d1─┬─d2─┐
2021-08-0533
└────────────┴────┴────┘

-- 获取月 EXTRACT(MONTH FROM date)
-- 对应函数 toMonth(date)
SELECT toDate('2021-08-05 21:50:25') as dt , EXTRACT(MONTH FROM dt) as d1,toMonth(dt) as d2;
┌─────────dt─┬─d1─┬─d2─┐
2021-08-0588
└────────────┴────┴────┘


-- 获取日 EXTRACT(DAY FROM date)
-- 对应函数 toDayOfMonth(date)
SELECT toDate('2021-08-05 21:50:25') as dt , EXTRACT(DAY FROM dt) as d1,toDayOfMonth(dt) as d2;
┌─────────dt─┬─d1─┬─d2─┐
2021-08-0555
└────────────┴────┴────┘

-- 获取小时 EXTRACT(HOUR FROM date)
-- 对应函数 toHour(date)
SELECT toDateTime('2021-08-05 21:50:25') as dt ,EXTRACT(HOUR FROM dt) as d1, toHour(dt) as d2;
┌──────────────────dt─┬─d1─┬─d2─┐
2021-08-05 21:50:252121
└─────────────────────┴────┴────┘

-- 获取分钟 EXTRACT(MINUTE FROM date)
-- 对应函数 toMinute(date)
SELECT toDateTime('2021-08-05 21:50:25') as dt , EXTRACT(MINUTE FROM dt) as d1,toMinute(dt) as d2;
┌──────────────────dt─┬─d1─┬─d2─┐
2021-08-05 21:50:255050
└─────────────────────┴────┴────┘

-- 获取秒 EXTRACT(SECOND FROM date)
-- 对应函数 toSecond(date)
SELECT toDateTime('2021-08-05 21:50:25') as dt , EXTRACT(SECOND FROM dt) as d1,toSecond(dt) as d2;
┌──────────────────dt─┬─d1─┬─d2─┐
2021-08-05 21:50:252525
└─────────────────────┴────┴────┘

9.2. INTERVAL

  • 进行日期计算的间隔,

  • 向后日期计算使用正数。后一天 INTERVAL 1 DAY

  • 向前计算时间时候复数。前一天 INTERVAL -1 DAY

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
-- 年间隔 INTERVAL 1 YEAR
-- 对应函数 addYears(date,years)
select toDate('2021-08-05 21:50:25') as dt, dt + INTERVAL 1 YEAR as d1,addYears(dt,1) d2;
┌─────────dt─┬─────────d1─┬─────────d2─┐
2021-08-052022-08-052022-08-05
└────────────┴────────────┴────────────┘

-- 季度间隔 INTERVAL 1 QUARTER 1个季度为三个月
-- 对应函数 addQuarters(date,years)
select toDate('2021-08-05 21:50:25') as dt, dt + INTERVAL 1 QUARTER as d1,addQuarters(dt,1) d2;
┌─────────dt─┬─────────d1─┬─────────d2─┐
2021-08-052021-11-052021-11-05
└────────────┴────────────┴────────────┘

-- 月份间隔 INTERVAL 1 MONTH
-- 对应函数 addMonths(date,months)
select toDate('2021-08-05 21:50:25') as dt, dt + INTERVAL 1 MONTH as d1,addMonths(dt,1) d2;
┌─────────dt─┬─────────d1─┬─────────d2─┐
2021-08-052021-09-052021-09-05
└────────────┴────────────┴────────────┘

-- 周间隔 INTERVAL 1 WEEk
-- 对应函数 addWeeks(date,weeks)
select toDate('2021-08-05 21:50:25') as dt, dt + INTERVAL 1 WEEk as d1,addWeeks(dt,1) d2;
┌─────────dt─┬─────────d1─┬─────────d2─┐
2021-08-052021-08-122021-08-12
└────────────┴────────────┴────────────┘

-- 日间隔 INTERVAL 1 DAY
-- 对应函数 addDays(date,days)
select toDate('2021-08-05 21:50:25') as dt, dt + INTERVAL 1 DAY as d1,addDays(dt,1) d2;
┌─────────dt─┬─────────d1─┬─────────d2─┐
2021-08-052021-08-062021-08-06
└────────────┴────────────┴────────────┘

-- 小时间隔 INTERVAL 1 HOUR
-- 对应函数 addHours(date,hours)
select toDateTime('2021-08-05 21:50:25') as dt, dt + INTERVAL 1 HOUR as d1,addHours(dt,1) d2;
┌──────────────────dt─┬──────────────────d1─┬──────────────────d2─┐
2021-08-05 21:50:252021-08-05 22:50:252021-08-05 22:50:25
└─────────────────────┴─────────────────────┴─────────────────────┘

-- 分间隔 INTERVAL 1 MINUTE
-- 对应函数 addMinutes(date,minutes)
select toDateTime('2021-08-05 21:50:25') as dt, dt + INTERVAL 1 MINUTE as d1,addMinutes(dt,1) d2;
┌──────────────────dt─┬──────────────────d1─┬──────────────────d2─┐
2021-08-05 21:50:252021-08-05 21:51:252021-08-05 21:51:25
└─────────────────────┴─────────────────────┴─────────────────────┘

-- 秒间隔 INTERVAL 1 SECOND
-- 对应函数 addSeconds(date,seconds)
select toDateTime('2021-08-05 21:50:25') as dt, dt + INTERVAL 1 SECOND as d1,addSeconds(dt,1) d2;
┌──────────────────dt─┬──────────────────d1─┬──────────────────d2─┐
2021-08-05 21:50:252021-08-05 21:50:262021-08-05 21:50:26
└─────────────────────┴─────────────────────┴─────────────────────┘

10. CASE条件表达式

1
2
3
4
5
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

11. 连接运算符

1
2
3
4
5
6
7
-- 连接符 '||'
-- 对应函数 concat(s1, s2)
select 'hello ' || 'world' as s1, concat('hello ','world') as s2;
┌─s1──────────┬─s2──────────┐
│ hello world │ hello world │
└─────────────┴─────────────┘

12. 创建 Lambda 函数

1
2
3
4
5
6
7
-- x -> expr – 
-- 对应函数 lambda(x, expr)

SELECT arraySort((x) -> x, [5,4,3,1,2,3]) as res;
┌─res───────────┐
│ [1,2,3,3,4,5] │
└───────────────┘

13. 创建数组

1
2
3
4
5
6
-- [x1, ...]
-- 对应函数 array(x1, ...)
select [1,1,3] as a1,array(1,2,3) as a2,toTypeName(a1) as type;
┌─a1──────┬─a2──────┬─type─────────┐
│ [1,1,3] │ [1,2,3] │ Array(UInt8) │
└─────────┴─────────┴──────────────┘

14. 创建元组

1
2
3
4
5
6
-- (x1, x2, ...)
-- 对应函数 tuple(x2, x2, ...)
select (1,'b',3.2) as t1,tuple(1,'a',0.1) as t2,toTypeName(t1) as type;
┌─t1──────────┬─t2──────────┬─type──────────────────────────┐
│ (1,'b',3.2) │ (1,'a',0.1) │ Tuple(UInt8, String, Float64) │
└─────────────┴─────────────┴───────────────────────────────┘

15. 结合方式

所有的同级操作符从左到右结合。例如, 1 + 2 + 3 会转换成 plus(plus(1, 2), 3)。

所以,有时他们会跟我们预期的不太一样。例如, SELECT 4 > 2 > 3 的结果是0。

为了高效, and 和 or 函数支持任意多参数,一连串的 AND 和 OR 运算符会转换成其对应的单个函数。

1
2
3
4
5
6
7
8
9
select 1 + 2 + 3;
┌─plus(plus(1, 2), 3)─┐
6
└─────────────────────┘

SELECT 4 > 2 > 3;
┌─greater(greater(4, 2), 3)─┐
0
└───────────────────────────┘

16. 判断是否为NULL

ClickHouse 支持 IS NULL 和 IS NOT NULL

16.1. IS NULL

  • 值为 NULL 返回 1(true)
  • 值不为 NULL 返回 0(false)
1
2
3
4
5
6
7

select * from (
select 'null is true' as s1, NULL as n1, isNull(n1) as isn
) t where n1 is NULL;
┌─s1───────────┬─n1───┬─isn─┐
null is true │ ᴺᵁᴸᴸ │ 1
└──────────────┴──────┴─────┘

16.2. IS NOT NULL

  • 值不为 NULL 返回 1(true)
  • 值为 NULL 返回 0(false)
1
2
3
4
5
6
select * from (
select 'null is true' as s1, NULL as n1, 'hello' as n2, isNotNull(n2) as isn
) t where n2 is NOT NULL;
┌─s1───────────┬─n1───┬─n2────┬─isn─┐
null is true │ ᴺᵁᴸᴸ │ hello │ 1
└──────────────┴──────┴───────┴─────┘

文章作者: hnbian
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hnbian !
评论
  目录