03、MySQL常见函数、分组函数、分组查询

常见函数

#进阶四、函数
/*
函数;类似于Java中的"方法"
为了解决某个问题,将编写的一系列命令集合封装在一起,对外仅仅暴露方法名以供外部调用
1、自定义方法(函数)
2、调用方法(函数)

常见函数:
1、字符函数
2、数学函数
3、日期函数
4、流程控制函数
*/

-- 1、字符函数
#concat 拼接
SELECT CONCAT('Hello,', first_name, last_name) AS str FROM employees;

#length 获取字节长度,由字符集决定
SELECT LENGTH('中国Hello');
#11=6+5

#char_length 获取字符长度
SELECT CHAR_LENGTH('Hello中国');
#7

#substring 截取字符串 SQL中字符串的起始索引从1开始
SELECT SUBSTRING('Hello,MySQL', 7);
#MySQL  7代表开始索引
SELECT SUBSTRING('Hello,MySQL', 1, 5);
#Hello  1代表起始索引,5代表截取的个数

#instr 返回字串第一次出现的索引
SELECT INSTR('Hello,Hello', 'llo');
#3

#trim 去除前后空格
SELECT TRIM('    JavaScript    ');
SELECT TRIM('x' FROM 'xxxxxJavaxxxxx');
#Java

# lpad 左填充
SELECT LPAD('Script', 3, 'x');
#为Script左填充x直到3位
#Scr
# rpad 右填充
SELECT RPAD('Java', 5, 'b');
#为Java右填充b直到5位
#Javab

#查询员工表中的姓名:姓首字母大写,其他字母小写,名所有字母大写,姓与名之间用_拼接,最后起别名
SELECT CONCAT(UPPER(SUBSTRING(first_name, 1, 1)), LOWER(SUBSTRING(first_name, 2)), '_', UPPER(last_name)) AS finalname
FROM employees;

# strcmp 比较两个字符串的大小
SELECT STRCMP('ABC', 'AAA');
#1

# left right
SELECT LEFT('ShawnYue', 5);
#Shawn
SELECT RIGHT('ShawnYue', 3);
#Yue

-- 2、数学函数
#abs 取绝对值
SELECT ABS(-2);
#2

#ceil 向上取整
SELECT CEIL(1.2);
#2
SELECT CEIL(1.12);
#2

#floor 向下取整
SELECT FLOOR(1.78);
#1

#round 四舍五入
SELECT ROUND(1.12);
#1
SELECT ROUND(1.50);
#2

SELECT ROUND(1.87232, 2);
#保留小数点后2位
#1.87

# truncate 截断
SELECT TRUNCATE(1.87121, 2);
#1.87


# mod 取余
SELECT MOD(10, 3);
#1
#余数的正负只与被除数有关

-- 3、日期函数
#now 获取当前日期时间
SELECT NOW();
#2020-07-22 21:33:38

#curdate 获取当前日期
SELECT CURDATE();
#2020-07-22

#curtime 获取当前时间
SELECT CURTIME();
#21:35:06

#datediff 获取两个日期的差
SELECT DATEDIFF(CURDATE(), '1998-11-08');
#7928

#date_format 格式化日期
SELECT DATE_FORMAT(CURDATE(), '%Y年%m月%d日');
#2020年07月23日

SELECT DATE_FORMAT(hiredate, '%Y年%m月%d日 %H时%i分%s秒') FROM employees;

#str 解析字符串
SELECT STR_TO_DATE('2019年7月1日', '%Y年%m月%d日');
#2019-07-01

-- 4、流程控制函数
# if函数
SELECT IF(100 > 90, '大于', '小于');
#大于

SELECT IF(commission_pct IS NOT NULL, salary * 12 * (1 + commission_pct) ,'没奖金')
FROM employees;

# case函数
/*
CASE 表达式
WHEN 值1 THEN 结果1
WHEN 值2 THEN 结果2
...
ELSE 结果n
END
*/
#部门编号为30,工资显示为double;部门编号为50,工资显示为triple;部门编号为60,工资显示为quadra;否则不变
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;


/*
CASE
WHEN 条件一 THEN 结果1
WHEN 条件二 THEN 结果2
...
ELSE 结果n
END
*/
#如果工资大于2w,显示级别为A;大于1.5w,显示级别为B;大于1w,显示级别为C;否则显示D
SELECT salary,
(CASE 
WHEN salary > 20000 THEN 'A'
WHEN salary > 15000 THEN 'B'
WHEN salary > 10000 THEN 'C'
ELSE 'D'
END) grade
FROM employees;

#将员工按首字母排序和姓名的长度排序
SELECT last_name, CHAR_LENGTH(last_name) len
FROM employees
ORDER BY SUBSTRING(last_name, 1, 1) ASC, len ASC;

分组函数

#进阶5、分组函数/聚合函数/统计函数
/*
分组函数往往用于将一组数据进行统计计算,最终得到一个值,所以又称聚合函数/统计函数。
1、常见的分组函数,sum()求和、avg()求平均数、max()求最大值、min()求最小值、count()计算非空字段值的个数
*/
#查询所有员工的工资和、工资平均值、最高工资、最低工资、有工资的个数
SELECT SUM(salary) 工资和, AVG(salary) 平均工资, MAX(salary) 最大工资, MIN(salary) 最低工资, COUNT(salary) 个数
FROM employees;
-- 工资和	平均工资	最大工资	最低工资	个数
-- 691400.00	6461.682243	24000.00	2100.00		107

SELECT MAX(last_name) FROM employees;
#Zlotkey
#按照字符串的字典顺序排序

SELECT MIN(last_name) FROM employees;
#Abel

#查询员工表中有奖金的人数
SELECT COUNT(commission_pct) FROM employees;
#35

#查询员工表中月薪大于5000的人数
SELECT COUNT(salary) FROM employees WHERE salary > 5000;
#58

#查询有领导的人数
SELECT COUNT(manager_id) FROM employees;
#106

#count的补充介绍
/*
count计算非空字段的个数
*/
SELECT COUNT(*) FROM employees;
#107 统计结果集的行数
#有一列数据不为NULL,就统计,除非某一行所有列都为NULL

SELECT COUNT(1) FROM employees;
#107
#和count(*)一致

#推荐使用count(*)

#搭配distinct使用
#查询有员工的部门个数
SELECT COUNT(DISTINCT department_id)
FROM employees;

分组查询

#进阶六、分组查询
/*
语法:
select 查询列表
from 表名
where 筛选条件
group by 分组列表;

1、特点:查询列表往往是分组函数或者分组的字段;
2、分组查询分为两类:(1):分组前筛选where,在group by之前;(2)分组后筛选having,在group by之后
*/
#计算每个工种的员工平均工资
SELECT AVG(salary) 平均工资, job_id
FROM employees
GROUP BY job_id;

#查询每个领导下的员工个数
SELECT manager_id, COUNT(*) 个 FROM employees GROUP BY manager_id;

#查询邮箱中包含a字符的部门的最高工资
SELECT department_id 部门编号, MAX(salary) 最高工资
FROM employees
WHERE email LIKE '%a%' AND department_id IS NOT NULL
GROUP BY department_id;


-- 分组前的筛选:where子句在group by之前执行
#查询每个领导下有奖金的员工的平均工资
SELECT manager_id 领导编号, TRUNCATE(AVG(salary), 2) 员工平均工资
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id;


-- 分组后的筛选:having子句在group by之后执行
#查询哪个部门的员工个数大于5
/*
错误版:
select department_id 部门, COUNT(*) 员工个数
from employees
where COUNT(*) > 5
group by department_id;
*/
# where后面不能使用分组函数
SELECT department_id 部门, COUNT(*) 员工个数
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 5;
# having后面可以使用分组函数


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

#领导编号>102的每个领导手下员工的最低工资大于5000的最低工资
SELECT manager_id 领导编号, MIN(salary) 最低工资
FROM employees
WHERE manager_id > 102
GROUP BY manager_id
HAVING MIN(salary) > 5000;

#每个工种有奖金的员工的最高工资>6000的工种编号和最高工资,并按最高工资降序
SELECT job_id 工种编号, MAX(salary) 最高工资
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING MAX(salary) > 6000
ORDER BY 最高工资 DESC;

-- 按多个字段分组
#查询每个工种每个部门的最低工资,并按最低工资降序
SELECT MIN(salary) 最低工资, job_id 工种编号, department_id 部门编号
FROM employees
GROUP BY job_id, department_id
ORDER BY 最低工资 DESC;
#工种一样,部门一样的才算做一组员工

/*
执行顺序:
1、from子句
2、where子句
3、group by子句
4、having子句
5、select子句
6、order by子句
*/

猜你喜欢

转载自www.cnblogs.com/shawnyue-08/p/13364936.html