MySQL数据库提供了很多函数,其中包括:

l 数学函数;

l 字符串函数;

l 日期和时间函数;

l 条件判断函数;流程控制函数;

l 系统信息函数;

l 加密函数;

l 格式化函数。

我们主要掌握前四种函数就可以啦~

第六章 常见函数

什么是函数?

为了解决某个问题,将编写的一系列的命令集合封装在一起,对外仅仅暴露方法名,供外部调用。

我们可以:

1、自定义方法(函数)

2、调用方法(函数)

叫什么 :函数名

干什么 :函数功能

常见函数:


mysql分组获取第一条数据_分组函数


一、字符函数

1、CONCAT 拼接字符


SELECT CONCAT('hello,',first_name,last_name)  备注, first_name, last_name FROM employees;


mysql分组获取第一条数据_字符串_02


2、LENGTH 获取字节长度


SELECT LENGTH('hello,郭襄');


3、CHAR_LENGTH 获取字符个数


SELECT CHAR_LENGTH('hello,郭襄');


注意:一个中文字符相当于三个字节(utf-8编码下)

4、SUBSTRING 截取子串

注意:起始索引从1开始。(python是从0开始的哦~)

方式1:substr(str,起始索引,截取的字符长度)

方式2:substr(str,起始索引)


SELECT SUBSTR('张三丰爱上了郭襄',1,3);
SELECT SUBSTR('张三丰爱上了郭襄',7);


5、INSTR获取字符第一次出现的索引


SELECT INSTR('三打白骨精aaa白骨精bb白骨精','白骨精');


结果为3

6、TRIM去前后指定的字符,默认是去空格


SELECT TRIM(' 虚  竹    ')  AS a;
SELECT TRIM('x' FROM 'xxxxxx虚xxx竹xxxxxxxxxxxxxxxxxx')  AS a;


注意是前后哦,中间的无法去除。

7、LPAD/RPAD 左填充/右填充


SELECT LPAD('木婉清',10,'a');
SELECT RPAD('木婉清',10,'a');


mysql分组获取第一条数据_分组函数_03


注:10代表期望的字符数量

8、UPPER/LOWER 变大写/变小写


#案例:查询员工表的姓名,要求格式:姓首字符大写,其他字符小写,名所有字符大写,且姓和名之间用_分割,最后起别名“OUTPUT”
SELECT CONCAT(UPPER(SUBSTR(first_name,1,1)),LOWER(SUBSTR(first_name,2)),'_',UPPER(last_name)) "OUTPUT"
FROM employees;


思考过程:

①姓首字符大写:SELECT UPPER(SUBSTR(first_name,1,1)) FROM employees;

②其他字符小写:SELECT LOWER(SUBSTR(first_name,2)) FROM employees;

③名所有字符大写:SELECT UPPER(last_name) FROM employees;

9、STRCMP 比较两个字符大小


SELECT STRCMP('aec','aec');


情况

结果

左边大

1

右边大

-1

相等

0

注:英文字符按abc的顺序,默认a大于b。

10、LEFT/RIGHT 截取子串


SELECT LEFT('鸠摩智',1);
SELECT RIGHT('鸠摩智',1);


mysql分组获取第一条数据_字段名_04


公式

含义

CONCAT(S1,S2,......,Sn)

连接S1,S2,......,Sn为一个字符串

CONCAT(s, S1,S2,......,Sn)

同CONCAT(s1,s2,...)函数,但是每个字符串之间要加上s

REPEAT(str, n)

返回str重复n次的结果

LOWER(s)/LCASE(s)

将字符串s的所有字母转成小写字母

LEFT(s,n)

返回字符串s最左边的n个字符

RIGHT(s,n)

返回字符串s最右边的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(【BOTH 】s1 FROM s)

去掉字符串s开始与结尾的s1

TRIM(【LEADING】s1 FROM s)

去掉字符串s开始处的s1

TRIM(【TRAILING】s1 FROM s)

去掉字符串s结尾处的s1

REPEAT(str, n)

返回str重复n次的结果

REPLACE(str, a, b)

比较字符串s1,s2

STRCMP(s1,s2)

比较字符串s1,s2

SUBSTRING(s,index,len)

返回从字符串s的index位置其len个字符

REPLACE(str, a, b)

用字符串b替换字符串str中所有出现的字符串a

STRCMP(s1,s2)

比较字符串s1,s2

SUBSTRING(s,index,len)

返回从字符串s的index位置其len个字符


二、数学函数

1、ABS 绝对值


SELECT ABS(-2.4);


2、CEIL 向上取整

返回大于等于该参数的最小整数


SELECT CEIL(-1.09);
SELECT CEIL(0.09);
SELECT CEIL(1.00);


分别返回-1,1,1

3、FLOOR 向下取整

返回小于等于该参数的最大整数


SELECT FLOOR(-1.09);
SELECT FLOOR(0.09);
SELECT FLOOR(1.00);


4、ROUND 四舍五入


SELECT ROUND(1.8712345);
SELECT ROUND(1.8712345,2);


5、TRUNCATE 截断


SELECT TRUNCATE(1.8712345,1);


6、MOD 取余


SELECT MOD(-10,3);
SELECT -10%3;
SELECT 10%3;
SELECT -10%-3;
SELECT 10%-3;


原理:

a%b = a-(INT)a/b*b

-10%3 = -10 - (-10)/3*3 = -1

其中-10/3取整为-3,-3*3=-9,-10-(-9)=-1


mysql分组获取第一条数据_mysql trim 索引_05


公式

含义

ABS(x)

返回x的绝对值

CEIL(x)

返回大于x的最小整数值

FLOOR(x)

返回大于x的最大整数值

MOD(x,y)

返回x/y的模

RAND(x)

返回0~1的随机值

ROUND(x,y)

返回参数x的四舍五入的有y位的小数的值

TRUNCATE(x,y)

返回数字x截断为y位小数的结果

SQRT(x)

返回x的平方根

POW(x,y)

返回x的y次方


三、日期函数

1、NOW


SELECT NOW();


返回日期+时间:'2020-12-30 17:32:11'

2、CURDATE


SELECT CURDATE();


返回日期:

2020-12-30

3、CURTIME


SELECT CURTIME();


返回时间:17:32:11

4、DATEDIFF


SELECT DATEDIFF('2020-12-29', '2020-12-30');


结果为-1

5、DATE_FORMAT


SELECT DATE_FORMAT('1998-8-16','%Y年%m月%d日 %H小时%i分钟%s秒') 出生日期;


结果为'1998年08月16日 00小时00分钟00秒'

6、STR_TO_DATE 按指定格式解析字符串为日期类型


-- 选择录用日期在1998-3-15前的人
SELECT * FROM employees
WHERE hiredate<STR_TO_DATE('3/15 1998','%m/%d %Y');


mysql分组获取第一条数据_字符串_06


mysql分组获取第一条数据_分组函数_07


公式

含义

CURDATE()/CURRENT_DATE()

返回当前日期

CURTIME()/CURRENT_TIME()

返回当前时间

NOW()

SYSDATE()

CURRENT_TIMESTAMP()

LOCALTIME()

LOCALTIMESTAMP()

返回当前系统日期时间

YEAR(date)

MONTH(date)

DAY(date)

HOUR(time)

MINUTE(time)

SECOND(time)

返回具体的时间值

WEEK(date)

WEEKOFYEAR(date)

返回一年中的第几周

DAYOFWEEK()

返回周几,注意:周日是1,周一是2,…,周六是7

WEEKDAY(date)

返回周几,注意:周1是0,周2是1,…,周日是6

DAYNAME(date)

返回星期:MONDAY,TUESDAY,…,SUNDAY

MONTHNAME(date)

返回月份:January,…

DATEDIFF(date1,date2)

TIMEDIFF(time1, time2)

返回date1 - date2的日期间隔

返回time1 - time2的时间间隔

DATE_ADD(datetime, INTERVALE expr type)

返回与给定日期时间相差INTERVAL时间段的日期时间

DATE_FORMAT(datetime ,fmt)

按照字符串fmt格式化日期datetime值

STR_TO_DATE(str, fmt)

按照字符串fmt对str进行解析,解析为一个日期

(1)DATE_ADD(datetime, INTERVAL, expr type)

  • 增加一年:SELECT DATE_ADD(NOW(), INTERVAL 1 YEAR);
  • 减少一年:SELECT DATE_ADD(NOW(), INTERVAL -1 YEAR); #可以是负数
  • 增加一年零一个月:SELECT DATE_ADD(NOW(), INTERVAL '1_1' YEAR_MONTH);#需要单引号

expr type类型:

  • YEAR, MONTH, DAY, HOUR, MINUTE, SECOND
  • YEAR_MONTH, DAY_HOUR, DAY_MINUTE, DAY_SECOND, HOUR_MINUTE, HOUR_SECOND, MINUTE_SECOND

(2)DATE_FORMAT(datetime, fmt)和STR_TO_DATE(str, fmt)

格式符

说明

格式符

说明

%Y

4位数字表示年份(2019)

%y

2位数字表示年份(19)

%M

月名表示月份(January,....)

%m

两位数字表示月份(01,…)

%b

缩写的月名(Jan.,Feb.,…)

%c

数字表示月份(1,2,3,...)

%D

英文后缀表示月中的天数(1st,2nd,3rd,...)

%d

两位数字表示月中的天数(01,02,...)

%e

数字形式表示月中的天数(1,2,3,4,5.....)

%H

两位数字表示小数,24小时制(01,02..)

%h和%I(大写i)

两位数字表示小时,12小时制(01,02..)

%k

数字形式的小时,24小时制(1,2,3)

%l(小写L)

数字形式表示小时,12小时制(1,2,3,4....)

%i

两位数字表示分钟(00,01,02)

%S和%s

两位数字表示秒(00,01,02...)

%W

一周中的星期名称(Sunday...)

%a

一周中的星期缩写(Sun.,Mon.,Tues.,..)

%w

以数字表示周中的天数(0=Sunday,1=Monday....)

%j

以3位数字表示年中的天数(001,002...)

%U

以数字表示年中的第几周,(1,2,3。。)其中Sunday为周中第一天

%u

以数字表示年中的第几周,(1,2,3。。)其中Monday为周中第一天

%T

24小时制

%r

12小时制

%p

AM或PM

%%

表示%


四、流程函数

1、IF函数


SELECT IF(100>9,'好','坏');


结果返回:好

2、CASE函数

①情况1 :实现等值判断

CASE 表达式:

WHEN 值1 THEN 结果1
WHEN 值2 THEN 结果2
...
ELSE 结果n
END

案例:

部门编号是30,工资显示为2倍

部门编号是50,工资显示为3倍

部门编号是60,工资显示为4倍

否则不变

显示 部门编号,新工资,旧工资


SELECT department_id,salary,
CASE department_id
WHEN 30 THEN salary*2
WHEN 50 THEN salary*3
WHEN 60 THEN salary*4
ELSE salary
END  newSalary
FROM employees;


②情况2:类似于多重IF语句,实现区间判断

CASE
WHEN 条件1 THEN 结果1
WHEN 条件2 THEN 结果2
...
ELSE 结果n
END

案例:如果工资>20000,显示级别A

工资>15000,显示级别B

工资>10000,显示级别C

否则,显示D


SELECT salary,
 CASE 
 WHEN salary>20000 THEN 'A'
 WHEN salary>15000 THEN 'B'
 WHEN salary>10000 THEN 'C'
 ELSE 'D'
 END
 AS  a
 FROM employees;


mysql分组获取第一条数据_分组函数_08


第六章 常见函数思维导图:


mysql分组获取第一条数据_字段名_09



第七章 分组函数

分组函数往往用于实现将一组数据进行统计计算,最终得到一个值,又称为聚合函数或统计函数

分组函数清单:

  • sum(字段名):求和
  • avg(字段名):求平均数
  • max(字段名):求最大值
  • min(字段名):求最小值
  • count(字段名):计算非空字段值的个数
#案例1 :查询员工信息表中,所有员工的工资和、工资平均值、最低工资、最高工资、有工资的个数
SELECT SUM(salary),AVG(salary),MIN(salary),MAX(salary),COUNT(salary) FROM employees;

#案例2:添加筛选条件
#①查询emp表中记录数:
SELECT COUNT(employee_id) FROM employees;
#②查询emp表中有佣金的人数:
SELECT COUNT(salary) FROM employees;
#③查询emp表中月薪大于2500的人数:
SELECT COUNT(salary) FROM employees WHERE salary>2500;
#④查询有领导的人数:
SELECT COUNT(manager_id) FROM employees;


count的补充介绍


#1、统计结果集的行数,推荐使用count(*)
SELECT COUNT(*) FROM employees;
SELECT COUNT(*) FROM employees WHERE department_id = 30;

SELECT COUNT(1) FROM employees;
SELECT COUNT(1) FROM employees WHERE department_id = 30;
-- 与COUNT(*)效果一致,但数据量大的话还是*比较高效

#2、搭配distinct实现去重的统计
#需求:查询有员工的部门个数
SELECT COUNT(DISTINCT department_id) FROM employees;


思考:每个部门的总工资、平均工资?


SELECT SUM(salary) ,department_id
FROM employees
GROUP BY department_id;



第八章 分组查询

语法:

select 查询列表

from 表名

where 筛选条件

group by

having

order by 排序列表;

执行顺序:

①from子句

②where子句

③group by 子句

④having子句

⑤select子句

⑥order by子句


mysql分组获取第一条数据_字符串_10


特点:

①查询列表往往是分组函数被分组的字段

②分组查询中的筛选分为两类

筛选的基表

使用的关键词

位置

分组前筛选

原始表

where

group by 的前面

分组后筛选

分组后的结果集

having

group by的后面

where——group by ——having

分组函数做条件只可能放在having后面!!!

1) 简单的分组


#案例1:查询每个工种的员工平均工资
SELECT job_id, AVG(salary)
FROM employees
GROUP BY job_id;

#案例2:查询每个领导的手下人数
SELECT COUNT(*),manager_id
FROM employees
WHERE manager_id IS NOT NULL
GROUP BY manager_id;


2)可以实现分组前的筛选


#案例1:查询邮箱中包含a字符的每个部门的最高工资
SELECT MAX(salary) 最高工资,department_id
FROM employees
WHERE email LIKE '%a%'
GROUP BY department_id;


#案例2:查询每个领导手下有奖金的员工的平均工资
SELECT AVG(salary) 平均工资,manager_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id;


3)可以实现分组后的筛选


#案例1:查询哪个部门的员工个数>5
#分析1:查询每个部门的员工个数
SELECT COUNT(*) 员工个数,department_id
FROM employees
GROUP BY department_id
HAVING  COUNT(*)>5;

#案例2:每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
SELECT job_id,MAX(salary)
FROM employees
WHERE commission_pct  IS NOT NULL
GROUP BY job_id
HAVING MAX(salary)>12000;


#案例3:领导编号>102的每个领导手下的最低工资大于5000的最低工资
#分析1:查询每个领导手下员工的最低工资
SELECT MIN(salary) 最低工资,manager_id
FROM employees
WHERE manager_id>102
GROUP BY manager_id
HAVING MIN(salary)>5000 ;


4)可以实现排序


#案例:查询没有奖金的员工的最高工资>6000的工种编号和最高工资,按最高工资升序
#分析1:按工种分组,查询每个工种有奖金的员工的最高工资
SELECT MAX(salary) 最高工资,job_id
FROM employees
WHERE commission_pct IS  NULL
GROUP BY job_id

#分析2:筛选刚才的结果,看哪个最高工资>6000
SELECT MAX(salary) 最高工资,job_id
FROM employees
WHERE commission_pct IS  NULL
GROUP BY job_id
HAVING MAX(salary)>6000

#分析3:按最高工资升序
SELECT MAX(salary) 最高工资,job_id
FROM employees
WHERE commission_pct IS  NULL
GROUP BY job_id
HAVING MAX(salary)>6000
ORDER BY MAX(salary) ASC;


5)按多个字段分组


#案例:查询每个工种每个部门的最低工资,并按最低工资降序
#提示:工种和部门都一样,才是一组
SELECT MIN(salary) 最低工资,job_id,department_id
FROM employees
GROUP BY job_id,department_id;


mysql分组获取第一条数据_分组函数_11