ClickHouse 14.常用操作符介绍


1. 介绍 ClickHouse 的操作符

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

2. 下标运算符

-- 数组中的下标运算符
-- 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')1a       │
└─────────┴────┴─────────┘

3. 负号

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

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

-- 乘号 '*'
-- 对应函数 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. 关系运算符

-- 相等 '=' ,'=='
-- 对应函数 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. 集合关系运算符

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. 逻辑非或非

-- 逻辑与 '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是真是假,每行都会被复制展开。

-- 条件运算符 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

-- 时间提取 ,从指定时间中提取某一部分
-- 从给定日期中提取部件。 例如,您可以从给定日期检索一个月,或从时间检索一秒钟。
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.
  • 使用示例
-- 获取年 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

-- 年间隔 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条件表达式

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. 连接运算符

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

12. 创建 Lambda 函数

-- 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. 创建数组

-- [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. 创建元组

-- (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 运算符会转换成其对应的单个函数。

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)

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)
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 !
评论
 上一篇
ClickHouse函数 1.算术,比较,取整,逻辑,哈希,条件,URL 函数 ClickHouse函数 1.算术,比较,取整,逻辑,哈希,条件,URL 函数
1. 算数函数1.1 求和 plusSELECT plus(12, 21), plus(10, -10), plus(-10, -10) ; ┌─plus(12, 21)─┬─plus(10, -10)─┬─plus(-10, -10)─┐
2021-08-08
下一篇 
ClickHouse元数据 8.其他元数据 ClickHouse元数据 8.其他元数据
1. contributors(CK贡献者)CK的贡献者名称列表,再此对所有 ClickHouse 的贡献着表示感谢! name type comment name String 2. macros(宏变量)包含动态变量的
2021-08-03
  目录