如何用函数实现判断包含字符的函数每行最大字符并将最大数值返回至MAX列?

对于数据库,大学时学的是Oracle,我的老天,那位教授大人说的话,我貌似听懂了,但一到实操,完全白瞎,当年在实验室,我连搭环境都搭不起来,最后那门课是61分过的,貌似。应该是教授看我每次课都坐第一排,还次次认真做笔记,给我的平时印象分,不然我是要重考的----------总而言之,我数据库学的不好。

出来工作之后,前面几家公司,开发的人根本没给我机会接触过数据库,因此就一直不会,直到几年前来到现在这家公司,测试大牛太多,人人都是高手的感觉,她们让我无地自容,并且数据库测试也是必做的工作,因此我被逼学会了------虽然早几年前就因为要面试而背会了很多SQL语句,但那完全是用来装样子的

  数据库的作用,把数据以表的形式存储起来,方便查询

2、RDBMS 关系型数据库系统
   行:一条记录,一个事物的信息
   列:字段,一个事物的某一个属性
   表:一个表中的所有的行是一类事物

进入数据库里,再看user表里root的密码

然后用”十一“点上的修改密码来将密码重置
再重启,重新输入新密码

在一般的关系型数据库,相信很多人都不怎么使用数组这个结构,如果真的需要数组,那么会选择将其变成数组格式的字符串进行存储。但在 ClickHouse 中,数组的使用频率是非常高的,因为它内置了大量和数组有关的函数。

└───────────┘ └─────────┘

当前的 ClickHouse 是 21.7.3.14 版本,关于数组的函数有 48 个,通过这个 48 个函数,我们可以对数组进行各种骚操作。当然也有一些函数不是专门针对数组的,但是可以用在数组身上,我们就也放在一起说了,下面就来依次介绍相关函数的用法。

empty:判断数组是否为空,如果一个数组不包含任何元素,返回 1;否则返回 0

└──────────────────┴────────────────┘

empty 不仅可以检测数组是否为空,还可以检测字符串。

└─────────────────┴───────────┘

notEmpty:判断数组是否不为空,如果一个数组包含至少一个元素,返回 1;不包含任何元素,则返回 0

└─────────────────────┴───────────────────┘ -- 同样可以作用于字符串 └────────────────────┴──────────────┘

length:返回数组的长度,该函数也可以返回字符串的长度

└─────────────────┴───────────────────┴──────────────────┴────────────┘
-- 数组元素的类型为 nothing,因为没有指定任何元素
└────┴─────────────────────┘
-- 采用最小类型存储,因为 1 和 2 都在 UInt8 的范围内
└───────┴────────────────────┘
-- 但是我们可以创建指定类型的数组
└────┴──────────────────────────────────┘

array:也是创建一个数组,和直接使用方括号类似。但是 array 函数要求必须至少传递一个常量,否则就不知道要创建哪种类型的数组。如果想创建指定类型的空数组,那么使用上面的 emptyArray* 系列函数即可

-- 不管是使用 array 创建,还是使用 [] 创建,里面的元素都必须具有相同的类型,或者能够兼容
└────────────────┴───────────┘

arrayConat:将多个数组进行合并,得到一个新的数组

-- SELECT 中起的别名可以被直接其它字段所使用
└───────┴─────────┴───────────┴───────────────────────────────────────────┘

arrayElement:查找指定索引的元素,索引从 1 开始,也可以通过方括号直接取值;另外也支持负数索引,-1 代表最后一个元素

└───────────────────────┴───────────────────────┘ └───────────────────────┴────────────────────────┘

has:判断数组里面是否包含某个元素,如果包含,返回 1;不包含,返回0

└─────────────┴─────────────┴────────────────┘ -- 嵌套数组也是可以的 └───────────────────────┘

hasAll:判断数组里面是否包含某个子数组,如果包含,返回 1;不包含,返回0

注意:空数组是任意数组的子集;Null 会被看成是普通的值;数组中的元素顺序没有要求;1.0 和 1 被视为相等

在 has 函数里面也有嵌套数组,但是维度不同。比如 has(a, b):如果 a 是维度为 N 的数组,那么 b 必须是维度为 N - 1 的数组;而 hasAll 则要求 a 和 b 的维度必须相同。

└─────────────────────┘ -- 我们说 SELECT 里面别名可以给其它字段使用,因此下面这种做法也是合法的 └─────────────────────┘

hasAny:判断两个数组里面是否有相同的元素,只要有 1 个相同的元素,返回 1;否则,返回 0

└───────────────────────┴───────────────────────────┘ └────────────────────────────────────┘
-- 两个数组的维度必须相同
└──────────────────────────────┴──────────────────────────────┘

indexOf:查找某个元素第一次在数组中出现的位置,索引从 1 开始;如果不存在,则返回 0

└───────────────────┴──────────────────┴────────────────────┘

arrayCount:查找一个数组中非 0 元素的个数,该数组类的元素类型必须是 UInt8,并且不能包含 Null 值。因为一旦包含 Null,那么类型就不是 UInt8 了,而是 Nullable(UInt8)

└───────────────────────┴─────────────────────────────┘

此外 arrayCount 还有一种用法,就是接收一个函数和一个数组:

└─────────────────┴──────────────────────────────────────────────────────────────┘

ClickHouse 中的函数类似于 C++ 中的 lambda 表达式,x -> x + 1 相当于将 arr 中的每一个元素都加上 1,但结果得到整型是 UInt16,所以需要使用 cast 转成 UInt8,否则报错。另外,加上 1 之后就没有为 0 的元素了,所以返回的结果是

countEqual:返回某个元素在数组中出现的次数

└────────────────────┴───────────────────────┘ └──────────────────────────────┘

光说不好理解,直接看例子,然后画图说明:

└──────────────────────────────────────────────────────────────┘

arrayEnumerateUniq 还可以接收多个数组,这些数据具有相同的长度,相信你已经知道它的作用了:

└────────────────────────────────────────────────────────┘ -- 举个不恰当的例子 -- 此时会将多个数组作为一个整体来进行判断,因此这些数组都必须有相同的长度

arrayPopBack:移除数组中的最后一个元素

└─────────────────────────┘

显然它是可以被嵌套的:

└─────────────────────────────────┘

注意:对空数组使用 arrayPopBack 不会报错,得到的还是空数组。

└──────────────────────────┘

和 arrayPopBack 一样,也可以被嵌套,并且对空数组使用也不会报错,还是得到空数组。

└───────────────────────────────────┘ └─────────────────────────────┘

添加的时候记得类型要匹配,如果添加了 Null,那么数组会变成 Nullable。

└──────────────────────────────────────┘

添加的时候记得类型要匹配,如果添加了 Null,那么数组会变成 Nullable。

  • 如果指定的长度比原来的长度大,那么会用零值从尾部进行填充
  • 如果指定的长度比原来的长度大,那么会从尾部进行截断
└──────────────────────────┴──────────────────────────┘

在填充的时候,也可以使用指定的值进行填充:

└──────────────────────────────┴────────────────────────────────┘ └─────────────────────────────┴────────────────────────────────┘

arraySort:对数据进行排序,然后返回

└──────────────────────┴───────────────────────────────┘

字符串会按照字典序排序返回,整型、浮点型、日期都会按照大小返回。

问题来了,如果我们希望按照字符串的长度排序该怎么办呢?所以 arraySort 还支持传递一个自定义函数:

-- 按照数组中元素的长度进行排序
└────────────────────────────────────────────────────────────┘
-- 先按照正负号排序,小于 0 的排在大于 0 的左边,然后各自再按照绝对值进行排序
└──────────────────────────────────────────────────────────────────────────────────┘

我去,这 ClickHouse 也太强大了吧,这简直不像是在写 SQL 了,都有点像写 Python 代码了,所以 ClickHouse 这么火不是没有原因的。

另外当出现空值或 NaN 的话,它们的顺序如下:

所以 arraySort 如果接收一个参数,那么该参数必须是一个数组,然后 ClickHouse 按照默认的规则进行排序;如果接收两个参数,那么第一个参数是匿名函数,第二个参数是数组,此时 ClickHouse 会按照我们定义的函数来给数组排序;但其实 arraySort 还可以接收三个参数,第一个参数依旧是函数,然后第二个参数和第三个参数都是数组,此时会用数组给数组排序,举个栗子:

-- 因为有两个数组,所以匿名函数要有两个参数,x 表示第一个数组、y 表示第二个数组
-- 首先不管排序规则是什么,最终输出的都是第一个数组
-- x, y -> y 就表示按照第二个数组来给第一个数组进行排序输出
└────────────────────────────────────────────────────────────┘
-- 只不过此时第二个数组就用不上了

该函数你可以认为它是先按照 arraySort 排序,然后将结果再反过来,举个栗子:

└─────────┴──────────────┘

至于其它用法和 arraySort 都是一样的,可以看做是在 arraySort 的基础上做了一次反转。不过有一点需要注意,那就是 Null 值和 NaN:

arrayUniq:返回数组中不同元素的数量

└────────────────────────────┘

也可以传递多个长度相同的数组,会依次取出所有数组中相同位置的元素,然后拼成元组,并计算这些不重复的元组的数量,举个栗子:

└──────────────────────────────────────────────────┘ └────────────────────────┘ -- || 表示字符串拼接,当 arrayJoin 展开成多行的时候,会自动和其它字段组合 └───┴───────────────────────────────────────────────────────┘

如果出现了多个 arrayJoin ,那么会做笛卡尔积:

└──────────────────────┴─────────────────────────┘

提到了 arrJoin,那么就必须提一下 groupArray,这算是一个聚合函数,它和 arrayJoin 作用相反,将多行数据合并成数组。

└────────────────────┘ -- 当然我们也可以将它作为一张表 └───────────────┘ └───────────────────┘

arrayDifference:计算数组中每相邻的两个元素的差值

-- 第一个元素固定为 0,第二个元素为 3 - 1,第三个元素为 4 - 3,以此类推
└───────────────────────────────────┘
└───────────────────────────────────┘

arrayEnumerateDense:返回一个和原数组大小相等的数组,并指示每个元素在原数组中首次出现的位置(索引都是从 1 开始)

-- 22 首次出现在索引为 1 的位置、1 首次出现在索引为 2 的位置
└─────────────────────────────────────────────┘

arrayIntersect:接收多个数组,并取它们的交集

└────────────────────────────────────────┴────────────────────────────────────────┘

arrayReduce:将一个聚合函数作用在数组上,举个栗子:

└────────────────────────────────┴────────────────────────────────┘

可能有人觉得直接用聚合函数不就好了,答案是不行的,因为这些聚合函数针对的都是多行结果集,而不是数组。

-- 相当于只有一行数据,所以返回其本身
-- 如果是 sum 就直接报错了, 因为数组之间不能进行加法运算
└───────────────────┘
-- 如果想返回 33,我们应该将这个数组给展开,变成多行
└──────────────────────────────┘

所以聚合函数针对的是多行,而不是数组,如果想用聚合函数,那么应该将数组给展开。或者使用这里的 arrayReduce,相当于将两步合在一起了。当然我们也可以不用 arrayReduce,因为 ClickHouse 为了数组专门提供了相应的操作,比如求数组中最大的元素可以使用更强大的

arrayReduceInRanges:对给定范围内的数组元素应用聚合函数,光说不好解释,直接看例子:

-- 会对数组中索引为 1 开始向后的 5 个元素进行 sum,结果为 15
-- 会对数组中索引为 2 开始向后的 4 个元素进行 sum,结果为 14
-- 会对数组中索引为 1 开始向后的 3 个元素进行 sum,结果为 6
└────────────────────────────────────────────────────────────────────────────┘
┌─v─────────┐
└───────────┘
└────────────────────────────┴───────────────────────┘ └─────────────────────────────────────────┘

我们之前还介绍了一个 arrayConcat,可以对比一下两者的区别

└──────────────────────────────────────┘

arrayCompact:从数组中删除连续重复的元素

└─────────────────────────────────────────────────┘

我们看到作用类似于之前介绍的 arrayDistinct,但两者还是有区别的。

└──────────────────────────────────────────────────┘ └───────────────────────────────────────────────────────┘

arrayMap:对数组中每一个元素都作用相同的函数,根据函数的返回值创建一个新的数组,非常常用的一个功能。

└──────────────────────────────────────────────────────────┘ ┌─v1──────┬─v2─┬─v3─┐ └─────────┴────┴────┘

当然也可以作用嵌套数组:

└────────────────────────────────────────────────────────────────────────────────────────────┘ └────────────────────────────────────────────────────────────────────────────────────────────┘ └────────────────────────────────────────────────────────────────────────────────────────────┘

也可以作用多个数组,这些数组的长度必须相等。此外,有多个数组,函数就要有多少个参数:

┌─v──────────┐ └────────────┘ ┌─v─────────────────────────┐ └───────────────────────────┘

arrayFilter:对数组中每一个元素都作用相同的函数,如果函数返回值为真(非 0),则该元素保留,否则不保留。

└────────────────────────────────────────────────────────────────┘ └──────────────────────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────────────────┘

arrayFill:对数组中每一个元素都作用相同的函数,如果函数返回值为真,则该元素保留,否则被替换为前一个元素。

└─────────────────────────────────────────────────────────────────────┘ -- 第一个元素永远不会被替换,2、3、4、5 都不满足条件,因此都要换成前一个元素 -- 换 2 的时候,2 已经变成了 1,所以 3 的前面是 1,于是 3 也会变成 1 -- 4 和 5 也是同理,因此最终所有值都会变成 1 └─────────────────────────────────────────────────────────────────────┘

arrayReverseFill:对数组中每一个元素都作用相同的函数,如果函数返回值为真,则该元素保留,否则被替换为后一个元素。注意:此时数组是从后往前扫描的

-- 2 会被替换成 5,1 还是 1,最后一个元素不会被替换
└────────────────────────────────────────────────────────────────────────────┘
-- 因为数组从后往前扫描,所以 4 变成 5、3 也会变成 5,所有值都会变成 5
└────────────────────────────────────────────────────────────────────────────┘

arrayMin:返回数组中最小的元素

┌─v1─┬─v2─┬─v3─┐ └────┴────┴────┘

arrayMin 里面还可以传递一个匿名函数:

└────────────────────────────────────────────────────────┘

会按照调用匿名函数的返回值进行判断,选择最小的元素,这里 33 在调用之后返回 -33,显然是最小值。但是这里有一个需要注意的地方,就是它返回的也是匿名函数的返回值。个人觉得应该返回 33 才对,应为我们指定函数只是希望 ClickHouse 能够按照我们指定的规则进行排序,而值还是原来的值,但 ClickHouse 这里设计有点莫测高深了。如果我们以字符串为例,那么会看的更加明显:

我们看到居然返回了一个 1,我们的本意是想选择长度最短的字符串,但是返回的是最短字符串的长度,也就是返回的不是 'a',而是 length('a')。

arrayMax:返回数组中最大的元素

┌─v1─┬─v2─┬─v3─┐ └────┴────┴────┘

也可以加上一个匿名函数,作用和 arrayMin 完全一样,并且返回的也是函数调用之后的结果。

└───────────────┴─────────────────────────┴─────────────────────┘

同样可以加一个匿名函数:

└─────────────────────────────────────────────────┘ └───────────────────────────────┘

同样可以加一个匿名函数:

└─────────────────────────────────────────────────────────────┘ └───────────────┴─────────────────────────┴─────────────────────┘

同样可以加一个匿名函数:

└─────────────────────────────────────────────────┘ └──────────────────────────────┘

同样可以加一个匿名函数:

└────────────────────────────────────────────────────────────────┴───────────────────────────────┘

以上就是关于 ClickHouse 数组的一些函数操作,可以说是非常强大了,不光是功能强大,用起来也很舒服,仿佛有种在写 Python 代码的感觉。当然以上并不是关于数组的全部操作(绝大部分),但说实话已经够用了,即使你当前的需求,某一个函数不能解决,那么也能多个函数组合来解决。比如我们想要计算两个数组中相同位置的元素的差,那么就可以这么做:

-- 一个函数即可解决
└──────────────────────────────────────────────────────────────────┘

再比如,计算数组中每个元素减去上一个元素的值,由于第一个元素上面没有值,那么设为空:

-- 最后让 arr 和它的对应元素依次相减即可 ┌─v─────────────────────┐ └───────────────────────┘

显然即使是复杂的需求,也可以通过多个函数组合完成,怎么样,是不是有点酷呢?ClickHouse 内建了很多的函数,这些函数给我们一种仿佛在用编程语言写代码的感觉。

我要回帖

更多关于 判断包含字符的函数 的文章

 

随机推荐