前言: 由于大一学习数据库不扎实,学到后面有点吃力,所以回过头来认真学习一边,写一些学习总结,提醒自己。也要告诫读者,把
基础打扎实
。读者觉得有用的话可以收藏点赞哦!
MySQL函数查询
1.1、单行函数
字符函数
1、LENGTH 获取参数的字节个数
SELECT LENGTH('join') # 4
# 如果是gbk,一个汉字占2个字节
# 如果是utf-8,一个汉字占3个字节
#-------------------------------
SELECT LENGTH('张三丰') # 9
#获取当前字符编码
SHOW VARIABLES LIKE '%char%'
2、concat 拼接字符串
SELECT CONCAT(last_name,'_',first_name) name
FROM employees
# 结果 K_ing_Steven ....
3、UPPER 、LOWER 大小写
SELECT UPPER('Join') # JOIN
SELECT LOWER('JOIN') # join
4、SUBSTR 字符截取
# SUBSTR重载
#SELECT SUBSTR(str FROM pos FOR len)
# SUBSTR(str FROM pos)
# SUBSTR(str,pos,len)
# SUBSTR(str,pos)
#-------------------------------
SELECT substr('李莫愁爱上陆展元',6) output #下标是从 1 开始的 =>陆展元
SELECT substr('李莫愁爱上陆展元',4,5) output #下标是从 1 开始的 =>爱上陆展元
案例:姓名中首字符用大写,其他字符用小写然后用_拼接起来
SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),LOWER(SUBSTR(last_name,2)),'_',LOWER(first_name)) as name
FROM employees
5、INSTR(str,substr) 返回子串
# 第一回出现的位置,如果没有返回 0
SELECT INSTR('杨不悔爱上了殷六叔','六叔') AS out_put # 8
6、TRIM()去空格
SELECT LENGTH(trim(' 张翠山 ')) AS out_put # 9
有时候这个函数不满如要求,比如aaaaa张翠aaaaa山aaaaa
把前后的a 去掉怎么办呢?
SELECT TRIM('a' FROM 'aaaaa张翠aaaaa山aaaaa') AS out_put # 张翠aaaaa山
注意点: 如果a前面有空格或后面有空格就只是去空格,如果你需要去掉a字符前面和后面就不能有空格
比如:
SELECT TRIM('a' FROM ' aaaaa张翠aaaaa山aaaaa') # aaaaa张翠aaaaa山
SELECT TRIM('a' FROM ' aaaaa张翠aaaaa山aaaaa ') # aaaaa张翠aaaaa山aaaaa
7、lpad 用指定的长度实现左填充指定的长度
SELECT LPAD('殷素素',10,'*') AS out_put # *******殷素素
SELECT LPAD('殷素素',2,'*') AS out_put # 殷素
#(如果长度小于给定的字符长度就从左边依次截取)
8、Rpad 用指定的长度实现右填充指定的长度
SELECT RPAD('殷素素',12,'ab') AS out_put # 殷素素ababababa
9、REPLACE 替换
SELECT REPLACE('张无忌爱上了周芷若','周芷若','赵敏') AS out_put
# 张无忌爱上了赵敏
后者替换前者
数字函数
1、ROUND(X) 四舍五入
SELECT ROUND(1.65) # 取整
SELECT ROUND(1.569,2) # 小数点后保留2位
2、CEIL(X) 向上取整
SELECT CEIL(1.02) # => 2
3、 FLOOR(X) 向下取整
SELECT FLOOR(9.99) # =>9
4、 TRUNCATE(X,D) 截取小数点后D位
SELECT TRUNCATE(1.699,1) # =>1.6
5、 MOD(N,M) 取模
SELECT MOD(10,3)
SELECT 10%3
扩展:MOD(a,b) 的计算 a-a/b*b
日期函数
1、NOW() 返回当前系统日期加时间
SELECT NOW(); # 2020-05-09 18:10:03
2、 CURDATE() 返回当前系统日期不包含时间
SELECT CURDATE(); # 2020-05-09
3、 CURTIME() 返回当前时间,不包含系统日期
SELECT CURTIME(); # 18:10:57
4、 可以获取指定的部分,年,月,日,小时,分钟,秒
SELECT YEAR(NOW()) 年
#这两种都可以
SELECT YEAR('1997-9-13') 年
SELECT YEAR('1997/9/13') 年
SELECT YEAR(hiredate) 年 FROM employees
SELECT MONTH(NOW()) 月
SELECT MONTHNAME(NOW()) 月 # => May 英文版书写
SELECT MONTH(hiredate) 月 FROM employees
SELECT DAY(NOW()) 日
# 只输出星期几没有几号
SELECT DAYNAME(NOW()) 日 # =>Thursday 英文版书写
SELECT DAYNAME('1997-9-13') 日 # =>Thursday 英文版书写
SELECT HOUR(NOW()) 小时
SELECT MINUTE(NOW()) 分
SELECT SECOND(NOW()) 秒
5、 STR_TO_DATE 通过指定的格式转换成日期
SELECT STR_TO_DATE('1/2 1997','%d/%c %Y') AS out_put
6、 data_format
SELECT DATE_FORMAT(NOW(),'%Y年%m月%d日') AS out_put
SELECT last_name,DATE_FORMAT(hiredate,'%m月%d日 %y年')
FROM employees
WHERE commission_pct IS NOT NULL
其他函数
1、版本号
SELECT VERSION(); # 8.0.19
2、DATABASE()
SELECT DATABASE(); # myemployees
3、USER()
SELECT USER(); # root@localhost
流程控制函数
1、 IF(expr1,expr2,expr3)
SELECT IF(TRUE,'真','假') # 真
SELECT IF(FALSE,'真','假') # 假
2、 case 函数使用一 switch case 的效果
案例 : 查询员工的工资,要求
部门号:30 ,显示的工资为1.1倍
部门号:40 ,显示的工资为1.2倍
部门号:50 ,显示的工资为1.3倍
其他部门,显示原工资
SELECT
salary 原始工资,
department_id 部门编号,
CASE
department_id
WHEN 30 THEN
salary * 1.1
WHEN 40 THEN
salary * 1.2
WHEN 50 THEN
salary * 1.3 ELSE salary
END AS 新工资
FROM
employees
2、 case 函数使用二: 类似于多重if
java 中
if(条件1){
语句一;
}else if(条件2){
语句二;
}
…
else{
语句n;
}
mysql中
case
WHEN 条件1 then 要显示的值1或语句1
WHEN 条件2 then 要显示的值2或语句2…
else 要显示的值n或语句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 等级
FROM
employees
1.2、分组函数
特点:
1、sum,avg 一般用于处理数值型;max,min,count可以处理任何类型
2、以上分组函数都忽略null值
3、可以和 DISTINCT 搭配,实现去重功能。
4、count函数的单独介绍一般使用count(*)
5、和分组函数一起查询的字段要求是group by后的字段
-
sum 求和
-
avg 平均值
-
max 最大值
-
min 最小值
-
count 计算个数
SELECT COUNT(*) FROM employees # 查询表中的行数。
SELECT COUNT(1) FROM employees # 查询表中的行数。
效率问题:
- MYISAM存储引擎下 COUNT()效率最高
- INNODB存储引擎下 COUNT(*)和COUNT(1)效率差不多
分组函数筛选条件
数据源 | 位置 | 关键字 | |
---|---|---|---|
分组前筛选 | 原始表 | GROUP BY子句前面 | WHERE |
分组后筛选 | 分组后的结果集 | GROUP BY子句后面 | HAVING |
分组函数做条件肯定放在 HAVING 子句中。
以下是案例巩固以上所以学
# 引入 查询每个部门的平均工资
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id
# 案例一: 每个工种的最高工资
SELECT MAX(salary),job_id
FROM employees
GROUP BY job_id
# 案例二: 查询每个位置上的部门个数
SELECT COUNT(*),location_id
FROM departments
GROUP BY location_id
# 1、添加分组前筛选条件
# 案例一: 查询邮箱中包含a字符的,每个部门的平均工资。
SELECT AVG(salary),department_id,email
FROM employees
WHERE email LIKE '%a%'
GROUP BY department_id
# 案例二: 查询有奖金的每个领导手下员工的最高工资
SELECT MAX(salary),manager_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id
# 2、添加复杂的(分组后)筛选条件
# 案例一:那个部门的员工个数大于2
# 步骤1.查询每个部门的员工个数
SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id
# 步骤2.根据第一的结果查询那个部门的员工个数大于2
SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id
HAVING count(*)>2
# 案例二: 查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
# 步骤1:查询每个工种有奖金的员工的最高工资
SELECT MAX(salary),job_id
FROM employees
WHERE commission_pct is not NULL
GROUP BY job_id
# 步骤2:>12000的工种编号和最高工资
SELECT MAX(salary),job_id
FROM employees
WHERE commission_pct is not NULL
GROUP BY job_id
HAVING MAX(salary) >12000
# 案例三: 查询领导编号>120的每个领导手下的最低工资>5000的领导编号是哪个,以及其最低工资。
# 步骤1.查询领导编号>120的每个领导手下的最低工资
SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id>120
GROUP BY manager_id
# 步骤2.最低工资大于5000的
SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id>120
GROUP BY manager_id
HAVING MIN(salary)>5000
# 3、按表达式或函数分组
# 案例一: 按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数>5 的有哪些。
SELECT COUNT(*) 个数,LENGTH(CONCAT(last_name,first_name)) 长度
FROM employees
GROUP BY 长度
HAVING 个数>5
# 4、按多个字段进行分组
# 案例: 查询每个部门每个工种的员工的平均工资
SELECT AVG(salary),department_id,job_id
FROM employees
GROUP BY department_id,job_id
# 5、添加排序
# 案例: 查询每个部门每个工种的员工的平均工资,并且按平均工资的高低进行排序
SELECT AVG(salary),department_id,job_id
FROM employees
GROUP BY department_id,job_id
ORDER BY AVG(salary) DESC
SELECT AVG(salary),department_id,job_id
FROM employees
GROUP BY department_id,job_id
ORDER BY AVG(salary) ASC # 升序
总结: 数据库这门语言呢,不难,但是要多练,没有捷径。读者觉得有用的话可以收藏点赞哦!