当前位置:网站首页>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;
#代码不全

#格式化
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`;
边栏推荐
猜你喜欢
![[redis learning 11] data persistence of distributed cache, master-slave cluster](/img/ea/1f5065ef7856f5028644912e29b642.png)
[redis learning 11] data persistence of distributed cache, master-slave cluster

虚拟机安装及配置

3D编程模式:依赖隔离模式

Qt development -- compilation of serial port assistant

3D programming mode: dependent isolation mode

The integrated monitoring system of ankerui distribution room realizes the online monitoring of the environment in the distribution room and ensures the safe operation of the equipment in the distribu

Creation of JS class and use of constructor constructor

如何解决mouseup事件失效的问题

修改市场活动表

测试不会被开发取代吗?
随机推荐
文件排序 (拓展)
Update and delete operations in Clickhouse of data warehouse series
远程预付费管理系统帮助物业解决收费难统计难问题
English grammar_ adverb
MySQL基础 增删改查练习
Document sorting (expansion)
C language pointer
[texstudio] [3] relatively complete paper typesetting template and bib file reference method
[antenna] [1] explanation of some nouns and simple concepts
3D編程模式:依賴隔離模式
安科瑞综合能效管理系统在数据中心的应用
[antenna] [2] explanation of some nouns and simple concepts, still
MySQL基础 DML与DDL学习
2022年5月29日16:05:09
redhat7 破解(重置)root密码
NetCore框架WTM的分表分库实现
Mock interview plan; Campus simulated interview plan; Job search simulation interview contest plan; Planning book of simulated job hunting competition of School of economics and management; College st
Oracle locally managed tablespaces
Hvv蓝队指北
Configure CONDA environment and pytoch installation