Mysql各种函数与注意

mysql常见函数

统计函数

  • count()函数,对于除*以外的任何参数,返回所选集合中非null值的行的数目;对于参数*是返回集合中所有的数目,包含null的行.没有where的count(*)是结果内部优化的,能快速地返回表中所有记录
  • sum:求表中某个字段的总和
  • avg函数:求表中某个值的平均值
  • max函数求表中某个字段的最大值
  • min函数求表中某个字段的最小值

数学函数

数学函数主要用于处理数字,包括整型和浮点数。下面介绍一下常用的几个数学函数。

ABS()函数

ABS()可以求出某字段值的绝对值。

FLOOR()函数

FLOOR()函数用于返回小于或等于参数x的最大整数。

RAND()函数

RAND()函数用于返回0~1之间的随机数。

TRUNCATE(x, y)函数

TRUNCATE(x, y)函数返回x保留到小数点后y位的值。

SQRT(x)函数

SQRT(x)函数用于求参数x的平方根。

下面看一下示例语句:

字符串函数

字符串函数主要用来处理数据表中的字符串。下面介绍一下常用的几个字符串函数。

UPPER(s)和UCASE(s)函数

UPPER(s)和UCASE(s)函数均可用于将字符串s中的所有哦字母变成大写字母。

LEFT(s, n)函数**

LEFT(s, n)函数返回字符串s的前n个字符。

SUBSTRING(s, n, len)函数

SUBSTRING(s, n, len)函数用于将字符串s的第n个位置开始获取长度len的字符串。

日期和时间函数

日期和时间函数是MySQL中最常用的函数之一,主要用于对表中的日期和时间数据进行处理。下面介绍一下几个常用的日期和时间函数。

CURDATE()和CURRENT_DATE()函数

CURDATE()和CURRENT_DATE()函数获取当前日期。

CURTIME()和CURRENT_TIME()函数

CURTIME()和CURRENT_TIME()函数获取当前时间。

NOW()函数

NOW()函数可以获取当前日期和时间,有同样功能的还有CURRENT_TIMESTAMP()、LOCALTIME() 、SYSDATE()和LOCALTIMESTAMP()。

mysql窗口函数

简介

在工种经常会有统计类的需求,对于复杂的统计,传统sql实现起来比较困难,这些需求有些共同点,需要在单表中满足某些条件的记录集内做一些函数操作.不适用窗口函数的话,可能要进行多次连表操作.不适用窗口函数的话,可能要进行多次连表操作,可读性差的同事,还会影响性能

窗口函数使用场景:对分组统计结果的每一条记录进行计算的场景下,使用窗口函数更好,注意是每一条,因为mysql的普通聚合函数的结果如group by是每组只有一条记录.

窗口函数

常用的聚合函数:

  1. count(col): 表示求指定列的总行数
  2. max(col): 表示求指定列的最大值
  3. min(col): 表示求指定列的最小值
  4. sum(col): 表示求指定列的和
  5. avg(col): 表示求指定列的平均值

窗口函数也称为OLAP(在线分析处理)函数,意思是对数据库数据进行实时分析处理,窗口函数就是为了实现OLAP而添加的标准SQL功能

窗口的概念非常重要可以理解为记录集合,窗口函数也就是在满足某种条件的记录集合上执行的特殊函数,对每条记录都要在此窗口内执行函数,有的函数,随着记录不同,窗口大小都是固定的,这属于静态窗口;有的函数则相反,不同的记录对应着不同的窗口,这种动态变化的窗口叫滑动窗口

窗口函数和聚合函数很容易混淆

  1. 聚合函数是将多条记录合为一条;而窗口函数是每条记录都会执行,查询结果并不会改变记录条数,有几条记录执行完还是几条
  2. 普通聚合函数也可以用于窗口函数中,赋予它窗口函数功能
    原因就在于窗口函数的执行顺序(逻辑上的)是在FROM,JOIN,WHERE,GROUP BY,HAVING之后,在ORDER BY,LIMIT,SELECT DISTINCT之前。它执行时GROUP BY的聚合过程已经完成了,所以不会再产生数据聚合。

mysql8才开始支持窗口函数

使用

窗口函数有over关键字,指定函数执行的范围,可以分成是三个部分:分组子句,排序子句,窗口子句

<函数名> over (partition by <分组的列> order by <排序的列> rows between <起始行> and <终止行>)

窗口的确定

分组子句 partition by

不分组可以写成partition by null或者直接不写

后面可以跟多个列

和group by的区别:前者不会压缩行数但是后者会,后者只能选取分组的列和聚合的列,也就是说group by生成的结果集与原表的行数和列数都不同

比如现在是这样的数据表

SELECT *,sum(age) over (partition by age) as '总年龄' from testemployee
id  name  dep_id age salary cus_id 总年龄
109    lhbOM    4    26    2002    4    24503443
110    NTcGX    10    28    2002    7    24503443
111    vneGU    7    23    2008    1    24503443
112    RdOIb    2    27    2002    9    24503443
113    GBNkN    2    25    2002    6    24503443
114    mwwTc    7    20    2005    3    24503443
115    RtuOM    4    26    2001    8    24503443
116    kSIMM    6    22    2008    6    24503443
117    knNYG    3    21    2000    9    24503443
118    nHwmT    7    26    2002    3    24503443
119    shHPe    1    28    2009    5    24503443
120    swehw    8    23    2005    9    24503443

group by生成的结果集与原表的行数和列数都有不同

排序字句 order by

不排序可以写order by null或者不写

asc或不写表示升序,desc表示降序

后面可以跟多个列 例如order by age,cus_id

窗口子句rows

  1. 起始行 N preceding/unbounded preceding
  2. 当前行:current row
  3. 终止行:N following/unbounded following

如果不写的话默认就是between unbounded preceding and unbounded following

总体流程

通过partition by和 order by 子句确定大窗口(定义出上接unbounded preceding和下界unbounded following)

通过row子句对每一行数据确定小窗口(滑动窗口)

对每行的小窗口内的数据并升成新的列

函数分类

排序类(序号函数)

rank,dense_rank,row_number

SELECT *,rank() over (partition by age) as '排名' from testemployee
  • row_number():不考虑并列
  • rank():考虑并列按年龄分组后作跳跃跑明
  • dense_rank():按班级分组后作连续排名,考虑并列

聚合类

sum,avg,count,max,min

跨行类(前后函数)

lag,lead

参数1:比较的列,参数2:便宜量,参数3:找不到的默认值,可以只传俩个参数

比如想找同部门内,id比自己低一名的年龄是多少

lag是低,lead是高

SELECT *,lag(id,1) over (partition by dep_id order by id) as '小id' from testemployee

分布函数

percent_rank()

用提:和之前的rank函数相关,每行按照如下公式计算:(rank-1)/(rows-1)

其中rank为rank函数产生的序号,row为当前窗口的记录总行数

cume_dist()

分组内大于等于当前rank值的分数/分组内总行数,这个函数比percent_rank用的多

头尾函数

first_value(expr)/last_value(expr)

得到分区中第一个/最后一个值

得到部门中第一个id

SELECT *,first_value(id) over (partition by dep_id order by id) as '小id' from testemployee

其他函数

  1. nth_value(expr, n)
  • 用途:返回窗口中第N个expr的值,expr可以是表达式,也可以是列名
  1. nfile()

用途:将分区中的有序数据分为n个桶,记录桶号。
此函数在数据分析中应用较多,比如由于数据量大,需要将数据平均分配到N个并行的进程分别计算,此时就可以用NFILE(N)对数据进行分组,由于记录数不一定被N整除,所以数据不一定完全平均,多出来的部分则依次加给第一组、第二组···直到分配完。

Last modification:November 17, 2023
如果觉得我的文章对你有用,请随意赞赏