函数
文章目录
将代码封装起来,需要的时候调用即可
- 提高了代码效率和可维护性
- 提高了用户对数据库的管理效率
单行函数
只对一行进行变换,每行返回一个结果
可以嵌套
数值函数
基本函数
函数 | 用法 |
---|---|
ABS(X) | 绝对值 |
SIGN(X) | 数字的符号(-1,0,1) |
PI() | 圆周率 |
CEIL(X),CEILING(X) | 向下取整 |
FLOOR(X) | 向上取整 |
LEAST(X1,X2,X3…) | 最小值 |
GREATEST(X1,X2,X3…) | 最大值 |
MOD(X,Y) | x/y的余数 |
RAND() | 返回0~1的随机值 |
RAND(X) | 返回0~1的随机值,x为种子值 (一个种子对应一个值) |
ROUND(X) | X四舍五入后取整 |
ROUND(X,Y) | X四舍五入后取小数点后Y位 |
TRUNCATE(X,Y) | 返回数字X截断为Y位小数的结果 |
SQRT(X) | X的平方根,X为负时返回NULL |
角度与弧度
函数 | 用法 |
---|---|
DRDIANS(X) | 将角度转化为弧度 |
DEGREES(X) | 将弧度转化为角度 |
三角函数
函数 | 用法 |
---|---|
SIN(X) | 正弦值,X为弧度值 |
ASIN(X) | 反正弦值,X为弧度值 |
COS(X) | 余弦值,X为弧度值 |
ACOS(X) | 反余弦值,X为弧度值 |
TAN(X) | 正切值,X为弧度值 |
ATAN(X) | 反正切值,X为弧度值 |
ATAN(m,n) | 两个参数的反正切值 |
COT(X) | 余切值,X为弧度值 |
指数与对数
函数 | 用法 |
---|---|
POW(X,Y),POWER(X,Y) | X的Y次方 |
EXP(X) | e的x次方 |
LN(X),LOG(X) | 以e为底的x的对数,当X<=0时,返回NUL |
LOG10(X) | 以10为底的x的对数,当X<=0时,返回NUL |
LOG2(X) | 以2为底的X的对数,当X<=0时,返回NUL |
进制转换
函数 | 用法 |
---|---|
BIN(X) | X的二进制编码 |
HEX(X) | X的16进制编码 |
OCT(X) | X的8进制编码 |
CONV(X,F1,F2) | F1进制的X变成F2进制 |
字符串函数
函数 | 用法 |
---|---|
ASCII(S) | S中第一个字符的ASCII码值 |
CHAR_LENGTH(S) | S的字符数,与CHARACTER_LENGTH(S)相同 |
LENGTH(S) | S的字节数 |
CONCAT(S1,S2,S3…,Sn) | 连接S1,S2,S3,…Sn作为一个字符串 |
CONCAT_WS(X,S1,S2,S3…,Sn) | 同CONCAT(S1,S2,S3…,Sn)函数,但每个字符串之间要加上X |
INSERT(str,idx,len,replacestr) | 字符串str从第idx位置开始,len个字符长的字串替换为字符串replacestr |
REPLACE(str,a,b) | b替换字符串str中所有出现的字符串a |
UPPER(S),UCASE(S) | S中所有小写字母转成大写字母 |
LOWER(S),LCASE(S) | S中所有的大写字母转成小写字母 |
LEFT(str,n) | str最左边的n个字符 |
RIGHT(str,n) | str最右边的n个字符 |
LPAD(str,len,pad) | pad对str最左边进行填充,直到str的长度为len个字符为止 |
RPAD(str,len,pad)` | pad对str最右边进行填充,直到str的长度为len个字符为止 |
LTRIM(S) | 去掉S左侧的空格 |
RTRIM(S) | 去掉S右侧的空格 |
TRIM(S) | 去掉S开始与结尾的空格 |
TRIM(s1 FROM S) | 去掉S开始与结尾的s1 |
TRIM(LEADING s1 FROM S) | 去掉S开始处的s1 |
TRIM(TRAILING s1 FROM S) | 去掉字符串S结尾处s1 |
REPEAT(str,n) | str重复n次 |
SPACE(n) | 返回n个空格 |
SRTCMP(s1,s2) | 比较s1,s2的ASCII码值的大小 |
SUBSTR(s,index,len) | s的index位置其len个字符,作用与SUBSTRING(s,n,len)、MID(s,n,len)作用相同 |
LOCATE(substr,str) | substr在字符串str中首次出现的位置,作用与POSITION(substr IN str)、INSTR(str,substr)相同,未找到,返回0 |
ELT(M,s1,s2,s3…sn) | 如果m=n,则返回sn |
FIELD(s,s1,s2,s3…sn) | s在字符串列表中第一次出现的位置 |
FIND_IN_SET(s1,s2) | s1在字符串s2中出现的位置,s2是一个以逗号分隔的字符串 |
REVERSE(s) | s反转后的字符串 |
NULLIF(value1,value2) | 比较两个字符串,如果相等,返回NULL;否则返回value1 |
日期和时间函数
获取时间、日期
函数 | 用法 |
---|---|
CURDATE() ,CURRENT_DATE() | 返回当前年、月、日 |
CURTIME() ,CURRENT_TIME() | 返回当前时、分、秒 |
NOW() /SYSDATE()/CURRENT_TIMESTAMP()/LOCALTIME()/LOCALTIMESRAMP | 当前系统日期和时间 |
UTC_DATE() | UTC日期 |
UTC_TIME() | UTC时间 |
日期与时间戳的转换
函数 | 用法 |
---|---|
UNIX_TIMESTAMP() | 以UNMIX时间的形式返回当前时间 |
UNIX_TIMESRAMP(date) | 将时间date以UNIX时间戳的形式返回 |
FROM_UNIXTIME(timestamp) | 将UNIX时间戳的时间转换为普通格式的时间 |
月份、星期、星期数、天数
函数 | 用法 |
---|---|
YEAR(date),MONTH(date),DAY(date) | 返回具体的日期值 |
HOUR(time),MINUTE(time),SECOND(time) | 返回具体的时间值 |
MONTHNAME(date) | 返回月份 |
DAYNAME(date) | 返回星期几 |
WEEKDAY(date) | 返回周几 |
QUARTER(date) | 返回日期对应的季度 |
WEEK(date),WEEKOFYEAR(date) | 一年中的第几周 |
DAYOFYEAR(date) | 一年中的第几天 |
DAYOFMONTH(date) | 月份中的第几天 |
DAYOFWEEK(date) | 返回周几(日1~7六) |
日期的操作
EXTRACT(type FROM date )
- 返回指定日期中特定的部分,type指定返回的值
type值 | 用法 |
---|---|
MICROSECOUD | 毫秒数 |
SECOND | 秒数 |
MINUTE | 分钟数 |
HOUR | 小时数 |
DAY | 天数 |
WEEK | 在一年中的第几个星期 |
MONTH | 在一年中的的几个月 |
QUARTER | 一年中第几个季度 |
YEAR | 返回日期的年份 |
SECOND_MICROSECOND | 返回秒和毫秒值 |
- 其它的也可以以上表最后一种的搭配方式搭配使用
时间和秒钟转换的函数
函数 | 用法 |
---|---|
TIME_TO_SEC(time) | 将time转化为秒并返回结果值 |
SEC_TO_TIME(seconds) | 将seconds描述转化为包含消失、分钟和秒的时间 |
日期的格式化与解析
函数 | 用法 |
---|---|
DATE_ADD(datetime,INTERVAL expr type) ADDDATE(date,INTERVAL expr type) | 给定日期时间相差INTERVAL时间段的日期时间 |
DATE_SUB(date,INTERVAL expr type) SUBDATE(date,INTERVAL expr type) | date相差INTERVAL时间间隔的日期 |
-
type取值
间隔类型 含义 HOUR 小时 MINUTE 分钟 SECOND 秒 YEAR 年 MONTH 月 DAY 日 YEAR_MONTH 年和月 -
其它情况可以按上表最后样式搭配使用
函数 | 用法 |
---|---|
ADDTIME(time1,time2) | time1+time2,time2为数字时代表秒 ,可以为负 |
SUBTIME(time1,time2) | time1-time2,time2为数字时代表秒 ,可以为负 |
DATEDIFF(date1,date2) | date-date2的日期间隔天数 |
TIMEDIFF(time1,time2) | time1-time2的时间间隔 |
FROM_DAYS(N) | 从0000年1月1日起,N天后的日期 |
TO_DAYS(date) | date距离0000年1月1日的天数 |
LAST_DAY(date) | 返回date所在月份的最后一天的日期 |
MAKEDATE(year,n) | 针对date所在月份的最后一天的日期 |
MAKETIME(hour,minute,second) | 将给定的小时、分钟和秒的组合成时间并返回 |
PERIOD_ADD(time,n) | time加上n后的时间 |
流程控制函数
MySQL中的流程处理函数主要包括IF()、IFNULL()和CASE()函数
函数 | 用法 |
---|---|
IF(value,value1,value2) | 如果value的值为TRUE ,返回value1,否则返回value2 |
IFNULL(value1,value2) | 如果value1不为NULL ,返回value1,否则返回value2 |
CASE WHEN 条件1 THEN 结果1 WHEN 条件2 THEN 结果2 …[ELSE resultn] END | 相当于Java的if... else if ... else... |
CASE expr WHEN 常量值1 THEN 值1 WEN 常量值2 THEN 值2 … | 相当于Java中的switch ... case ... |
CASE WHEN ... THEN ... WHEN ... THEN ... ELSE ...END
SELECT last_name,salary
CASE WHEN salary >= 15000 THEN '富裕'
WHEN salary >= 10000 THEN '小康'
WHEN salary >= 8000 THEN '屌丝'
ELSE '低保户' /*默认值,若无此选项则默认返回NULL*/
END "details",department_id
FROM emlopyees;
CASE ... WHEN ... THEN ... WHEN ... THEN ... ELSE ... END
/*查询部门号为10,20,30的员工信息
10号工资1.1倍;20号工资1.2倍;30号工资1.3倍*/
SELECT employee_id,last_name,department_id,salary
CASE department_id
WHEN 10 THEN salary * 1.1
WHEN 20 THEN salary * 1.2
WHEN 30 THEN salary * 1.3
END "details"
FROM employees
WHERE department_id IN (10,20,30);
加密与解密函数
函数 | 用法 |
---|---|
MD5(str) | 字符串str的md5加密后的值,也是一种加密方式。若参数为NULL,则会返回NULL |
SHA(str) | 从原明文密码str计算并返回加密后的密码字符串,当参数为NULL,则会返回NULL。SHA加密算法比MD5更安全 |
MySQL信息函数
函数 | 用法 |
---|---|
VERSION() | 当前MySQL的版本号 |
CONNECTION_ID() | 当前MySQL服务器的连接数 |
USER(),CURRENT_USER(),SYSTEM_USER() ,SESSION_USEEER() | 当前连接MySQL的用户名,返回结果格式为“主机名@用户名” |
CHARSER(value) | 字符串value自变量的字符集 |
COLLATION(value) | 字符串value的比较规则 |
其他函数
函数 | 用法 |
---|---|
FORMAT(value,n) | 对数字value进行格式化后的结果数据。n表示四舍五入 后保留到小数点后n位 |
CONV(value,from,to) | 将value的值进行不同进制之间的转换 |
INET_ATON(ipvalue) | 将以点分隔的IP地址转化为一个数字 |
INET_NTOA(value) | 将数字形式的IP地址转化为以点分隔的IP地址 |
BENCHMARK(n,expr) | 将表达式expr重复执行n次。用于测试MySQL处理expr表达式的效率 |
CONVERT(value USING char_code) | 将value所使用的字符编码修改为char_code |
聚合函数
对一组数据进行汇总的函数,输入的时一组数据的集合,输出的时单个值
常用
函数 | 用法 | 备注 |
---|---|---|
AVG | 平均值 | 仅适用于数值类型的字段(或变量) |
SUM | 求总和 | 仅适用于数值类型的字段(或变量) |
MIN | 最大值 | 适用于数值、字符串、时间类型的字段(或变量) |
MAX | 最小值 | 适用于数值、字符串、时间类型的字段(或变量) |
COUNT
- 计算指定字段在查询结构中出现的个数(不包含NULL值的)
COUNT(*);``COUNT(1);
COUNT(具体字段);
不一定对!- 计算指定字段出现的个数时,是不计算
NULL
值的。
- 计算指定字段出现的个数时,是不计算
COUNT(*);``COUNT(1);``COUNT(具体字段);
- 如果使用的是MyISAM存储引擎,三者效率相同
- 如果使用的是InnoDB存储引擎,
COUNT(*)
=COUNT(1)
>COUNT(具体字段)
AVG=SUM/COUNT
GROUP BY
将表中的数据分成若干组
/*查询各个department_id,job_id的平均工资*/
SELECT department_id,job_id,AVG(salary)
FROM emloyees
GROUP BY department_id,job_id;/*结果和分组顺序无关*/
- SELECT中出现在非组函数的字段必须声明在GROUP BY中,反之,GROUP BY中声明的字段可以不出现在SELECT中。
SELECT department_id,job_id,AVG(salary)
FROM emloyees /*错误的语句*/
GROUP BY department_id;
GROUP BY
声明在WHERE
、FROM
后面;LIMIT
前面GROUP BY
中使用WITH ROLLUP
WITH ROLLUP
在所有查询出的分组记录之后增加一条记录,该记录统计记录的数量WITH ROLLUP
和ORDER BY
是相互排斥的,不能同时使用
HAVING
用来过滤数据
- 当过滤条件中有聚合函数时,则此过滤条件必须声明在HAVING中
- 当过滤跳进啊中没有聚合函数时,则此过滤条件在WHERE中或HAVING中都可以。建议声明在WHERE中,效率会更高
- 如果过滤条件中使用了聚合函数,则必须使用
HAVING
来替换WHERE
。否则,报错。 HAVING
必须声明在GROUP BY
的后面
/*查询各个部门中最高工资比1000高的部门信息*/
SELECT department_id,MAX(salary)
FROM employees
GROUP BY department_id
HAVING MAX(salary)>10000;
- 开发中,使用
HAVING
的前提是SQL中使用了GROUP BY
/*查询各个部门中最高工资比1000高的部门信息*/
SELECT department_id,MAX(salary)
FROM employees
GROUP BY department_id
HAVING MAX(salary)>10000 AND department_id IN (10,20,30,40);
/*IN也可以放于WHERE中,而且放于WHERE中效率也更高*/
WHERE与HAVING的对比
- 从范围上来讲,HAVING的范围更广
- 如果过滤条件中没有聚合函数:WHERE的执行效率高于HAVING
SELECT底层执行原理
SELECT语句的完整结构
SQL92语法
SELECT ...,...,...(存在聚合函数)
FROM ...,...,...
WHERE 多表连接的条件 AND 不包含聚合函数的过滤条件
GROUP BY ...,...
HAVING 包含聚合函数的过滤条件
ORDER BY ...,...(ASC / DESC)
LIMIT ...,...
SQL99语法
SELECT DISTINCT ...,...,...(存在聚合函数)
FROM ...(LEFT / RIGHT)JOIN ... ON ...
(LEFT / RIGHT)JOIN ... ON ...
WHERE 不包含聚合函数的过滤条件
GROUP BY ...,...
HAVING 包含聚合函数的过滤条件
ORDER BY ...,...(ASC / DESC)
LIMIT ...,...
SELECT语句执行过程
FROM ...,...
->ON
-> (LEFT/RIGHT JOIN)
-> WHERE
-> GROUP BY
-> HAVING
->SELECT
->DISTINCT
->ORDER BY
->LIMIT