clickhou类型错误、聚合函数错误——字段别名的注意事项
最近接触了clickhou,不得不说性能是真的强⼤,即使最简单的使⽤,不加任何优化也⽐常规数据库要快上很多,所以⼀直把它当作普通数据库来⽤,也⽀持sql语句,上⼿起来很快,不过今天写需求时⽤到了ca when语句,从⽽引出了clickhou字段别名的⼀些⽤法。
⾸先说⼀下别名指的是:lect columnA as columnB 这种⽤法。
圣诞节快乐英语怎么读(得出的结论均为⾃⼰摸索,未查到相关资料,如有错误多多指正)
最⼤不同:上⼀个字段的别名可在下⾯的字段中直接使⽤
这个是接触ck时最不习惯的问题,因为以前接触过的数据库没有过这种⽤法,所以在使⽤ck时遇到了很多错误。举例:
mysql数据库
mysql> lect 1 as a ,a +1 as b;
ERROR 1054 (42S22): Unknown column 'a' in 'field list'
⼀个简单的查询,但是会报错,即上⼀个字段的别名是不能在接下来被识别的。
clickhou:
SELECTrelate
1 AS a,
a + 1 AS b
┌─a─┬─b─┐
│ 1 │ 2 │
└───┴───┘
1 rows in t. Elapd: 0.004 c.
但是在ck⾥,它是可以被识别的 但是也会导致下⾯的字段中都会被强制替换。意思就如果表中原来有⼀个字段名是 “num” ,对其进⾏sum求和后,还是取了原来⼀样的别名 即:sum(num) as num
那接下来的字段是识别不到原来的num的,说的有点啰嗦,直接上测试:
建测试表:
CREATE TABLE test123
ENGINE = TinyLog() AS
SELECT
'a' AS name,spreadout
1 AS num
UNION ALL
SELECT
'a' AS name,
2 AS num
UNION ALL
native american
SELECT
'a' AS name,
cass啤酒广告3 AS num
UNION ALL
SELECT
'b' AS name,
4 AS num
:) lect * from test123 ;
┌─name─┬─num─┐
│ a │ 3 │
│ b │ 4 │
│ a │ 1 │
│ a │ 2 │
└──────┴─────┘
4 rows in t. Elapd: 0.004 c.
测试语句:
SELECT
sum(num) AS num,
sum(num + 1) AS num_1
FROM test123;
Received exception from rver (version 20.12.3):
Code: 184. DB::Exception: Received from 10.***.***.***:9000. DB::Exception: Aggregate function sum(num) is found inside another aggregate function in qu ery: While processing sum(num) AS num.
0 rows in t. Elapd: 0.004 c.
sue
可以看到,这种写法在ck中会报错 Aggregate function sum(num) is found inside another aggregate,但是传统数据库是⽀持这种写法的,开始的时候不知道这个特性,
还以为是聚合函数的问题,看了半天聚合函数的⽂档。
奥斯卡金曲下载但是⼀旦发现这个特性之后就会觉得它很实⽤!⽐如求占⽐的时候可以直接⽤算好的结果:
⽽且虽然和传统数据库不⼀样,不过规避它的⽅式也很简单,只要取的别名不和原来字段名⼀样就好了。
SELECT
sum(num) AS num1,
sum(num + 1) AS num_1
FROM test123
气球英语┌─num1─┬─num_1─┐
│ 10 │ 14 │
└──────┴───────┘
1 rows in t. Elapd: 0.004 c.
但是很多时候为了美观(偷懒),就不想取新的名字,⼤多数时候也是没什么影响的,不过今天就遇到了问题,就是这个别名的识别不仅作⽤在lect语句中,甚⾄
还作⽤在where语句中!
SELECT if(num > 1, '⼤于1', '⼩于1') AS num
FROM test123
王强口语
WHERE num > 1
jonny deepReceived exception from rver (version 20.12.3):
Code: 386. DB::Exception: Received from 10.***.***.***:9000. DB::Exception: There is no supertype for types String, UInt8 becau some of them are String /FixedString and some of them are not: while executing 'FUNCTION greater(if(greater(num, 1), '⼤于1', '⼩于1') : 5, 1 : 1) -> greater(if(greater(num, 1), '⼤于1', '⼩于1'), 1) UInt8 : 6'.
0 rows in t. Elapd: 0.004 c.
就这么⼀个简单的类型错误:There is no supertype for types String, UInt8 becau some of them are String/FixedString and some of them are not: while executing,排查了半天(当然也是遇到的错误的语句要⽐这个复杂,涉及到了ca when的时间判断等,甚⾄在写这篇博客的时候我还以为是ca when的问题。。。)
这么⼀来相当于直接顶替了传统数据库中having 的⽤法,所以各位如果也遇到了以上错误,可以注意下别名的问题,是不是有类似⽤法。20211210更新:并不能代替hvaing⽤法,当别名是聚合函数字段的别名时,还是会报错,⽼⽼实实⽤having关键字就好了…只不过hvaing⾥也可以直接⽤别名代替。