当前位置:网站首页>MySQL基础 函数篇

MySQL基础 函数篇

2022-06-09 08:50:00 Maximize+

函数类似于方法,函数的通常概念是可以单独存在的个体单元,也是最小的单元组成。
函数一般都是封装代码用来方便多次调用,或增加主程序代码的可读性。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

数值函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果放入数值为因子,因子一样则两组结果一致。
在这里插入图片描述
在这里插入图片描述
第二个参数意为保留小数点的位数。
在这里插入图片描述
这种情况下会变为0,如果为-2则变变为 100,满足四舍五入的五则为200
在这里插入图片描述
该函数为截位,不会产生四舍五入。
在这里插入图片描述
负数直接为0;

单行函数嵌套

在这里插入图片描述
先运算括号里的函数,再运算括号外的函数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

字符串函数

在这里插入图片描述

#字符串函数
#ASCII() 获取字符的ASCII表值,CHAR_LENGTH和LENGTH()返回字符串的长度,第一个是按照字节返回长度
SELECT ASCII('A'),CHAR_LENGTH('HELLO'),CHAR_LENGTH('我们'),
LENGTH('HELLO'),LENGTH('我们')
FROM DUAL;
#字符串连接函数
SELECT CONCAT(emp.last_name,' worked for ',mgr.`last_name`) AS "结果集"
FROM employees emp JOIN employees mgr 
WHERE emp.`manager_id` = mgr.`employee_id`;
#带有分隔符号的连接函数
SELECT CONCAT_WS('-','Hello','Java','Hello','Spring MVC...')AS "Hello Demo";
#字符串的索引是从1开始的
#从2开始到3的数据替换成 aaaa
#第二个函数意为将字符串中的ll替换成mmm
#第二个函数的数据如果不存在,则替换失败,数据还是原来的数据,不会报错
SELECT INSERT("helloworld",2,3,'aaaaa'),REPLACE('hello','ll','mmm') AS "结果集" FROM DUAL;
#大写、小写函数 如果目标已大写或小写则无视
SELECT UPPER('hello java'),LOWER('HELLO JAVASCRIPT') FROM DUAL;
#类似于截取,不过分了截取的方向
SELECT LEFT('hello',2),RIGHT('hello',3);
#占位补充对齐函数 
#LPAD:右对齐效果
#RPAD:左对齐效果
SELECT e.`employee_id`,e.last_name,LPAD(e.`salary`,'10','*')
FROM employees e;
SELECT e.`employee_id`,e.last_name,RPAD(e.`salary`,'10','*')
FROM employees e;

在这里插入图片描述
在这里插入图片描述

#字符串函数
#去除首尾空格
SELECT CONCAT('---',TRIM(' h e lo '),'***') FROM DUAL;
#去除左边空格
SELECT CONCAT('---',LTRIM(' h e lo '),'***') FROM DUAL;
#去除右边空格
SELECT CONCAT('---',RTRIM(' h e lo '),'***') FROM DUAL;
#去除开始或结尾的参数
SELECT CONCAT('---',LTRIM(' h e lo '),'***') ,
TRIM('o' FROM 'oohello')
FROM DUAL;
#重复四次参数,产生空格 #如果左边比右边大则返回 1 相同返回0 小于返回-1
SELECT REPEAT('hello',4),LENGTH(SPACE(5)),STRCMP('abc','abd') FROM DUAL;
#截取字符串 如果不给予参数则默认全部截取(第一个参数的位置开始)
SELECT SUBSTR('hello',2,2)FROM DUAL;
#locate 获取参数1在参数2出现的位置 无视大小写 如果没有匹配到则返回0
SELECT LOCATE('l','hello') FROM DUAL;
#返回指定参数位置的字符串内容
SELECT ELT(2,'Hello Java','Hello Java Script','Java JQuery','Hello MySQL','Hello JBDC')FROM DUAL;
#寻找该字符串在字符串列表中首次出现的位置
SELECT FIELD('Hello MySQL','Hello Java','Hello Java Script','Java JQuery','Hello MySQL','Hello JBDC') FROM DUAL;
#寻找该字符串在字符串列表中首次出现的位置 其中s2是一串以逗号分开的字符串
SELECT FIND_IN_SET('Hello MySQL','Hello Java,Hello Java Script,Java JQuery,Hello MySQL,Hello JBDC') FROM DUAL;
#反转字符串 比较两个字符串,如果相等返回null 否则返回第一个参数
SELECT REVERSE('依天洛'),NULLIF('乐正绫','洛天依'),NULLIF('乐正绫','乐正绫')FROM DUAL;

日期和时间函数

在这里插入图片描述

#日期和时间类型函数
#获取日期时间
#获取日期,时间,当前系统日期和时间,获取世界标准日期时间
SELECT CURDATE(),CURTIME(),NOW(),UTC_DATE(),UTC_TIME();

在这里插入图片描述

#日期与时间戳的转换
SELECT UNIX_TIMESTAMP(),UNIX_TIMESTAMP('2022-6-15 20.09:13'),
FROM_UNIXTIME(1653912553),FROM_UNIXTIME(1655294953) 
FROM DUAL;

在这里插入图片描述

#获取月份、星期、星期数、天数等函数
SELECT YEAR(CURDATE()),MONTH(CURDATE()),DAY(CURDATE()),
HOUR(CURTIME()),MINUTE(NOW()),SECOND(SYSDATE())
FROM DUAL;

SELECT MONTHNAME("2012-8-27"),DAYNAME('2011-8-27'),WEEKDAY('2020-10-26'),
QUARTER(CURDATE()),WEEK(CURDATE()),DAYOFYEAR(NOW()),DAYOFMONTH(NOW()),
DAYOFWEEK(NOW()) FROM DUAL;

日期操作函数

在这里插入图片描述
在这里插入图片描述

#获取当前秒位
SELECT EXTRACT(SECOND FROM NOW()) FROM DUAL;
#获取当前日期
SELECT EXTRACT(DAY FROM NOW()) FROM DUAL;
#返回天和分钟值
SELECT EXTRACT(HOUR_MINUTE FROM NOW()) FROM DUAL;
#返回天和小时
SELECT EXTRACT(DAY_HOUR FROM NOW()) FROM DUAL;

时间和秒钟转换的函数

TIME_TO_SEC(time):将time转换为秒并返回结果值,转换公式为:小时X3600+分钟X60+秒
SEC_TO_TIME(seconds):将seconds描述转换为包含小时,分钟和秒的时间

#时间和秒钟转换函数
SELECT TIME_TO_SEC(CURTIME()),SEC_TO_TIME('75761')
FROM DUAL;

计算日期和时间函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#计算日期和时间函数
#相当于加了一年
SELECT DATE_ADD(NOW(),INTERVAL 1 YEAR) FROM DUAL;
#相当于减了一年
SELECT DATE_ADD(NOW(),INTERVAL -1 YEAR) FROM DUAL;
#SUB本身就是代表减 这里相当于减10年
SELECT DATE_SUB(NOW(),INTERVAL 10 YEAR) FROM DUAL;

SELECT DATE_ADD(NOW(),INTERVAL 1 DAY) AS "col1",
DATE_ADD('2021-10-21 23:32:12',INTERVAL 1 SECOND)AS "col2",
ADDDATE('2021-10-21 23:32:12',INTERVAL 1 SECOND)AS "col3",
DATE_ADD('2021-10-21 23:32:12',INTERVAL '1_1' MINUTE_SECOND) AS "col4",
DATE_ADD(NOW(),INTERVAL -1 YEAR) AS "col5",#可以是负数
DATE_ADD(NOW(),INTERVAL '1_1' YEAR_MONTH) AS "col6"#需要单引号
FROM DUAL; 
#代码不全

**p is 35 35:19**

#格式化
SELECT DATE_FORMAT(CURDATE(),'%Y-%M-%D'),DATE_FORMAT(NOW(),'%Y-%m-%d'),TIME_FORMAT(CURTIME(),'%H:%i:%S') FROM DUAL;
SELECT DATE_FORMAT(NOW(),'%Y-%M-%D %h:%i:%S %W %w %T %r') FROM DUAL;

解析

在这里插入图片描述

SELECT STR_TO_DATE('2022-May-31st 11:12:35 Tuesday 2 11:12:35 11:12:35 AM','%Y-%M-%D %h:%i:%S %W %w %T %r');
SELECT GET_FORMAT(DATE,'USA') FROM DUAL;

流程控制函数

在这里插入图片描述

#流程控制函数
#IF(value,value1,value2)
SELECT last_name,salary,IF(salary>=6000,'高工资','低工资')
FROM employees;
SELECT last_name,commission_pct,IF(commission_pct IS NOT NULL,commission_pct,0) "details"
,salary*12*(1+IF(commission_pct IS NOT NULL,commission_pct,0))"annual_sal"
FROM employees;
#IFNULL(VALUE1,VALUE2):看做是IF(VALUE,VALUE1,VALUE2)的特殊情况
SELECT last_name,commission_pct,IFNULL(commission_pct,0) "details"
FROM employees;
#CASE WHEN ... THEN...WHEN...THEN...ELSE...END
#类似于Java的 if elseif elseif...else
SELECT last_name,salary,CASE WHEN 
salary>=15000 THEN '高薪'
WHEN salary >= 10000 THEN '潜力股'
WHEN salary >= 8000 THEN '小青年'
ELSE '草根' END "details" FROM employees;
#CASE WHEN THEN WHEN THEN ELSE END
/* 若部门号为10,则打印其工资的1.1倍 20号部门,则打印其工资的1.2倍,30号部门打印其工资的1.3倍 其他部门,打印其工资的1.4倍 */
SELECT e.`employee_id`,e.`last_name`,e.`department_id`,e.`salary`,
CASE e.`department_id` WHEN 10 THEN e.`salary` * 1.1
WHEN  20 THEN e.`salary` * 1.2
WHEN 30 THEN `salary` * 1.3
ELSE `salary` * 1.4 END '结果'
FROM employees e;


/* 查询部门号为10,20,0的员工信息 若部门号为10,则打印其工资的1.1倍 20号部门,则打印其工资的1.2倍,30号部门打印其工资的1.3倍 */
SELECT e.`employee_id`,e.`last_name`,e.`department_id`,e.`salary`,
CASE e.`department_id` WHEN 10 THEN e.`salary` * 1.1
WHEN  20 THEN e.`salary` * 1.2
WHEN 30 THEN `salary` * 1.3
END '结果'
FROM employees e
WHERE e.department_id IN (10,20,30);

加密与解析

在这里插入图片描述

#加密与解析
#PASSWORD()在MySQL8.0中弃用
#MD5不可逆,只能再次通过MD5()来进行euqals对比
SELECT MD5('MySQL'),SHA('MySQL')
FROM DUAL;
#encode也被弃用了 
#SELECT ENCODE('atguigu','mysql') from dual;
#select DECODE(ENCODE('atguigu','mysql'),'mysql') from dual;

MySQL信息函数

在这里插入图片描述

#数据库信息函数

SELECT VERSION(),CONNECTION_ID(),DATABASE(),SCHEMA(),
USER(),CURRENT_USER(),CHARSET('尚硅谷'),COLLATION('尚硅谷')
FROM DUAL;

其他函数

在这里插入图片描述

#其他函数
#四舍五入格式化 如果N小于或等于0则只保留整数位
SELECT FORMAT(123.125,2) FROM DUAL;
#进行不同的进制转换 2 16 2
SELECT CONV(16,10,2),CONV(8888,10,16),CONV(NULL,10,2) FROM DUAL;
#将IP地址转换为数字
SELECT INET_ATON('192.168.1.100') FROM DUAL;
#将数值转换为IP地址
SELECT INET_NTOA(3232235876) FROM DUAL;
#BENCHMARK 检测表表达式的执行效率情况
SELECT BENCHMARK(100000,MD5('mysql')) FROM DUAL;
#将value所使用的字符编码改成第二个参数的字符集
SELECT CHARSET('atguigu'),CHARSET(CONVERT('atguigu' USING 'gbk')) FROM DUAL;

单行函数练习

#显示系统时间
SELECT NOW(),SYSDATE(),CURRENT_TIMESTAMP(),LOCALTIME(),LOCALTIMESTAMP()#掌握一个就行了
FROM DUAL;
#查询员工,姓名,工资,以及工资提供百分之20%后的结果(new salary)
SELECT e.`last_name`,e.`salary`,e.salary*1.2 AS "new salary"
FROM employees e;
#将员工的姓名按首字母排序,并写出姓名的长度(legnth)
SELECT last_name,LENGTH(last_name) "name_length"
FROM employees
#首字母排序
#order by last_name asc;
#姓名长度排序
ORDER BY name_length ASC;
#查询员工id,last_name,salary,并作为一个列输出,别名为OUT_PUT
SELECT CONCAT(employee_id," ",last_name," ",salary) AS "OUT_PUT"
FROM employees;  
#查询公司各员工的年数、工作的天数,并按工作年数排序
SELECT e.`employee_id`,ROUND(DATEDIFF(CURDATE(),e.`hire_date`)/365,1) "worked_years",DATEDIFF(CURDATE(),e.`hire_date`) "worked_days"
FROM employees e
ORDER BY worked_years DESC;
#查询员工姓名,hire_date,department_id,满足下面条件
#雇佣时间在1997年之后,department_id为80或90或110,commission_pct不为空
SELECT last_name,hire_date,department_id
FROM employees
WHERE department_id IN (80,90,100) 
AND commission_pct IS NOT NULL
#and hire_date >= '1997-01-01';#存在隐式转换
#and date_format(hire_date,'%Y-%m-%d') > '1997-01-01';#显示格式化转换 日期---->字符串
#and date_format(hire_date,'%Y') >= '1997';#显示转换 格式化
AND hire_date>=STR_TO_DATE('1997-01-01','%Y-%m-%d')#显转换操作 解析:字符串->日期
#查询公司中入职超过一万天的员工姓名、入职时间
SELECT e.last_name,e.hire_date
FROM employees e
WHERE DATEDIFF(CURDATE(),e.`hire_date`)>= 10000; 
#做一个查询,产生下面的结果
#<last_name>earns<salary>mothly but wants <salary*3>
SELECT CONCAT(last_name,' earns ',TRUNCATE(salary,0),' mothly but wants ',TRUNCATE(salary*3,0)) AS "Dream Salary"
FROM employees;
#使用case_when,按照下面的条件
/*job grde AD_PRES A ST_MAN B IT_PROG C SA_REP D ST_CLERK E 产生下面的结果 */
SELECT last_name "Last_name",job_id "Job_id",CASE job_id 
WHEN 'AD_PRES' THEN 'A'
WHEN 'ST_MAN' THEN 'B'
WHEN 'IT_PROG' THEN 'C'
WHEN 'SA_REP' THEN 'D'
WHEN 'ST_CLERK' THEN 'E' END "Grade"
FROM employees;

聚合函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#聚合函数
#常见的几个聚合函数
#AVG/SUM avg和sum只使用与数值,如果是其他数据则毫无意义
SELECT AVG(salary),SUM(salary),AVG(salary)*107,SUM(last_name)
FROM employees;
#MAX/MIN 适用于数值、字符串、时间类型的字段
SELECT MAX(salary),MIN(salary),MAX(last_name),MIN(last_name),MAX(hire_date),MIN(hire_date)
FROM employees;
# COUNT
#作用:计算指定字段在查询结构中出现的个数 
SELECT COUNT(employee_id),COUNT(salary)
FROM employees;
#通过count来查询有多少条记录 count不会将null统计到结果集中,所以不一定每个字段都可以正常统计
SELECT COUNT(*),COUNT(commission_pct)
FROM employees;
#使用count来进行平均工资
SELECT AVG(salary),SUM(salary)/COUNT(salary)
FROM employees;
#公式AVG = SUM / COUNT
SELECT AVG(commission_pct),SUM(commission_pct)/COUNT(commission_pct),
SUM(commission_pct)/107
FROM employees;
#查询公司平均奖金率
#错的的写法 因为没有计算没有奖金率的员工
SELECT AVG(commission_pct) FROM employees;
#正确的两种写法
SELECT SUM(commission_pct)/COUNT(IFNULL(commission_pct,0))
FROM employees;
SELECT AVG(IFNULL(commission_pct,0))
FROM employees;

在这里插入图片描述

GROUP BY的使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#聚合函数
#GROUP BY 的使用
#查询各个部门的平均工资
SELECT e.`department_id`,AVG(salary),SUM(salary)
FROM employees e
GROUP BY e.`department_id`;
#查询各个job_id的平均工资
SELECT job_id,AVG(salary)
FROM employees
GROUP BY job_id;
#查询各个department_id,job_id的平均工资
#方式一
SELECT department_id,job_id,AVG(salary)
FROM employees
GROUP BY department_id,job_id;
#方式二
SELECT department_id,job_id,AVG(salary)
FROM employees
GROUP BY job_id,department_id;
#错误的方式 job_id会只显示一个
SELECT department_id,job_id,AVG(salary)
FROM employees
GROUP BY department_id;
#结论:SELECT中出现非组函数的字段必须声明在GROUP BY中,反之GROUP BY中声明的字段不一定要出现在SELECT中
#GROUP BY 声明在FROM后面、WHERE后面,ORDER BY前面,LIMIT前面
SELECT department_id,AVG(salary)
FROM employees
GROUP BY department_id WITH ROLLUP;
#查询每个部门的平均工资,按平均工资升序排列
#正常需求
SELECT department_id,AVG(salary) salary_sal
FROM employees
GROUP BY department_id
ORDER BY salary_sal ASC;
#异常结果 并不适合参与排序 with roolup关键字
SELECT department_id,AVG(salary) salary_sal
FROM employees
GROUP BY department_id WITH ROLLUP
ORDER BY salary_sal ASC;

HAVING的使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最后的聚合函数的笔记和代码

在这里插入图片描述
在这里插入图片描述

此截图是精华

在这里插入图片描述

#聚合函数
#HAVING的使用 :过滤数据
#查询各个部门中最高工资比10000高的部门信息
#错误写法
SELECT department_id,MAX(salary)
FROM employees
WHERE MAX(salary)>10000
GROUP BY department_id;
#要求:如果过滤条件中使用了聚合函数,则必须使用HAVING来替换WHERE否则报错
#HAVING必须声明在GROUP BY 后面
#开发中我们使用HAVING前提是SQL中使用了GROUP BY 。
#正确写法
SELECT department_id,MAX(salary)
FROM employees
GROUP BY department_id HAVING MAX(salary)>10000;
#查询部门id为10,20,30,40中最高工资比10000高的部门信息
#方式一
SELECT department_id,MAX(salary)
FROM employees
WHERE department_id IN (10,20,30,40)
GROUP BY department_id HAVING MAX(salary)>10000;
#方式二
SELECT department_id,MAX(salary)
FROM employees
GROUP BY department_id HAVING MAX(salary)>10000 AND department_id IN (10,20,30,40);
#当过滤条件有聚合函数时,则此过滤条件必须声明在HAVING中,当过滤条件中没有聚合函数时,则此过滤
#条件声明在WHERE中或HAVING中都可以,但是建议声明在WHERE中。
/* WHERE与HAVING对比 HAVING的使用范围更广,也可以做到WHERE做不到的事情比如充当聚合函数的过滤条件 如果过滤条件中没有聚合函数,WHERE的执行效率要高于HAVING */
#SQL的底层执行原理
#关于SQL92和SQL99的区别
/* SQL92 SELECT ...,...(存在聚合函数) FROM ...,... WHERE 多表的连接条件 AND 不包含聚合函数的连接条件 GROUP BY ...,... HAVING 包含聚合函数的连接条件 ORDER BY ...,...(ASC/DESC) LIMIT ...(偏移量),...(显示数量) SQL99 SELECT ...,...(存在聚合函数) FROM ... (LEFT/RIGHT)JOIN ... ON 多表连接的条件 (LEFT/RIGHT)JOIN ... ON WHERE 不包含聚合函数的连接条件 GROUP BY ...,... LIMIT ...(显示数据) OFFSET(偏移量) (UNION ALL) ...(全满连接实现 SELECT) */
#SQL语句的执行过程
#WHERE先执行,而且WHERE会筛选数据,不会执行冗余的数据
#为什么WHERE不能充当HAVING是因为GROUP BY在WHERE后面执行,此时还没有分组,所以WHERE无法使用分组
#关于别名为什么字段的别名不能在WHERE中使用,根据执行顺序可以看出,SELECT在WHERE的后面并且在ORDER BY
#的后面,所以ORDER BY可以使用字段别名,而表别名可以在WHERE中使用的原因是表别名声明在了FROM 而FROM是最先执行的
#FROM ...,...-> ON(连接条件)-> (LEFT/RIGHT JOIN)-> WHERE-> GROUP BY-> HAVING->SELECT(查询的字段)-> 
#DISTINCT(去重)-> ORDER BY->LIMIT
#集合函数练习
#where子句可否使用组函数进行过滤?
#WHERE语句不能当组函数的过滤条件 
#查询公司员工工资的最大值,最小值,平均值,总和
SELECT MAX(e.`salary`),MIN(salary),AVG(IFNULL(salary,0)),SUM(e.`salary`)
FROM employees e;
#查询个job_id的员工工资的最大值,最小值,平均值,总和
SELECT job_id,MAX(salary),MIN(salary),AVG(salary),SUM(salary)
FROM employees
GROUP BY job_id;
#选择具有各个job_id的员工人数
SELECT e.`job_id`,COUNT(*)
FROM employees e
GROUP BY job_id;
#查询员工最高工资和最低工资的差距
SELECT MAX(salary),MIN(salary),MAX(salary) - MIN(salary) AS "工资差距"
FROM employees;
#查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的员工不计在内
SELECT manager_id,MIN(salary)
FROM employees
WHERE manager_id IS NOT NULL
GROUP BY manager_id HAVING MIN(salary)>=6000;
#查询所有部门的名字,location_id,员工数量和平均工资,并按平均工资降序
SELECT d.`department_name`,d.`location_id`,COUNT(e.`employee_id`),AVG(e.`salary`),e.`salary`
FROM departments d LEFT JOIN employees e
ON d.`department_id` = e.`department_id`
GROUP BY d.`department_name`,d.`location_id`
ORDER BY e.`salary` DESC;
#查询每个工种、每个部门的部门名称、工种名和最低工资
SELECT d.`department_name`,e.`job_id`,MIN(e.`salary`)
FROM departments d LEFT JOIN employees e
ON d.`department_id` = e.`department_id`
GROUP BY d.`department_name`,e.`job_id`;
原网站

版权声明
本文为[Maximize+]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_55868059/article/details/125051464