1、IFNULL( , );
两个参数,第一个参数需要判断的字段,第二个是默认值 ,当前⾯的值是null的时候,使⽤后⾯的默认值。
select ifnull(null,100); --> 100
select ifnull(10,20); --> 10
select ifnull(comm,0) from emp; --> ifnull 在此时会执行很多次,就会有很多的返回值。
2、IF ( , , );
if 函数有三个参数,第一个参数 boolean(布尔类型true false) , 第二个参数和第三个参数都是值,前⾯的条件如果成⽴,取值第⼀个,否则取值第⼆个。
select if(10>20,1,0);
mysql> select if(sal > ifnull(comm,0) ,sal,comm) from emp;
3、case (难点)
语法:case when ... then ... else ... end
分析:
- case 开头
- end 结尾
- 中间是 类似于 if else
注: 一行case when ... then ... else ... end 只能处理一个字段的数据。
1)行转列
# 使用if 来编写这个需求:
select sname,
if(subject='语文',score,0) 语文,
if(subject='数学',score,0) 数学,
if(subject='英语',score,0) 英语,
if(subject='历史',score,0) 历史,
if(subject='政治',score,0) 政治,
if(subject='体育',score,0) 体育
from sc;
+--------+------+------+------+------+------+------+
| sname | 语文 | 数学 | 英语 | 历史 | 政治 | 体育 |
+--------+------+------+------+------+------+------+
| 张小三 | 78 | 0 | 0 | 0 | 0 | 0 |
| 张小三 | 0 | 77 | 0 | 0 | 0 | 0 |
| 张小三 | 0 | 0 | 90 | 0 | 0 | 0 |
| 张小三 | 0 | 0 | 0 | 89 | 0 | 0 |
| 张小三 | 0 | 0 | 0 | 0 | 0 | 80 |
| 李小四 | 0 | 90 | 0 | 0 | 0 | 0 |
| 李小四 | 0 | 0 | 80 | 0 | 0 | 0 |
| 李小四 | 0 | 0 | 0 | 0 | 0 | 88 |
| 李小四 | 0 | 0 | 0 | 0 | 88 | 0 |
| 李小四 | 0 | 0 | 0 | 78 | 0 | 0 |
| 王小五 | 90 | 0 | 0 | 0 | 0 | 0 |
| 王小五 | 0 | 0 | 80 | 0 | 0 | 0 |
| 王小五 | 0 | 0 | 0 | 0 | 89 | 0 |
| 王小五 | 0 | 0 | 0 | 0 | 0 | 90 |
+--------+------+------+------+------+------+------+
select sname,
sum(if(subject='语文',score,0)) 语文,
sum(if(subject='数学',score,0)) 数学,
sum(if(subject='英语',score,0)) 英语,
sum(if(subject='历史',score,0)) 历史,
sum(if(subject='政治',score,0)) 政治,
sum(if(subject='体育',score,0)) 体育
from sc group by sname;
select sname,
sum(case when subject='语文' then score else 0 end) '语文',
sum(case when subject='数学' then score else 0 end) '数学',
sum(case when subject='英语' then score else 0 end) '英语',
sum(case when subject='历史' then score else 0 end) '历史',
sum(case when subject='政治' then score else 0 end) '政治',
sum(case when subject='体育' then score else 0 end) '体育'
from sc group by sname;
+--------+------+------+------+------+------+------+
| sname | 语文 | 数学 | 英语 | 历史 | 政治 | 体育 |
+--------+------+------+------+------+------+------+
| 张小三 | 78 | 77 | 90 | 89 | 0 | 80 |
| 李小四 | 0 | 90 | 80 | 78 | 88 | 88 |
| 王小五 | 90 | 0 | 80 | 0 | 89 | 90 |
+--------+------+------+------+------+------+------+
# 此时的需求是添加一列,这一列就是英文即可,一列 == 1个case
# 以下写法有点类似于if:
select *,
case
when subject ='语文' then 'chinese'
when subject ='数学' then 'Math'
when subject ='英语' then 'english'
when subject ='历史' then 'history'
when subject ='政治' then 'politics'
when subject ='体育' then 'sport'
end 英文学科名称
from sc;
# case的另一种写法: 类似于switch的写法
select *,
case subject
when '语文' then 'chinese'
when '数学' then 'Math'
when '英语' then 'english'
when '历史' then 'history'
when '政治' then 'politics'
when '体育' then 'sport'
end 英文学科名称
from sc;
4、exists(难点)
顾名思义,就是判断数据是否存在的!exists的作用为判断一个表中的数据,是否在另外的一张表中能够查询到与之对应的数据
语法:
select xxx from 表 where [not] exists (集合)
注:使用exists 编写sql,效率要比连接查询和子查询高!
# 案例1: 查询有员工的部门
select * from dept where deptno in (select distinct deptno from emp);
select * from dept where exists(
select * from emp where emp.deptno = dept.deptno
);
# 查询一个数据是否存在,存在里面的结果集中,如果存在,显示出来,不存在不显示。里面查询的是什么 # 结果集不重要,主要存在即可。
# 案例2: 查询没有员工的部门
select * from dept where not exists(
select * from emp where emp.deptno = dept.deptno
);
# 案例3: 查询有下属的员工信息
select * from emp where exists(
select * from emp e2 where e2.mgr = emp.empno
);
# 若一个表中存在两级以上的关联,则关联自身查询
# exists : 都可以使用我们以前的sql语句替换,但是使用exists 执行效率高。
5、字符串函数
# 字符串是万能的!!!不管在任何学科中!!!
# 1、获取字符串⻓度
select char_length('Hello');
# 2、使字符串中的小写字母变⼤写
select upper('Hello');
select UCASE('Hello');
# 3、使字符串中的大写字母变小写
select lower('Hello');
select lcase('Hello');
# 4、去除空⽩字符串
select trim(' Hello ');-- 左右两边的空⽩字符全部切掉
select ltrim(' Hello ');-- 只切除左边的空⽩字符
select rtrim(' Hello ');-- 只切右边
# 5、⽐较两个字符串是否相等,⽐较的肯定是内容
select strcmp('hello','hello');-- 如果相等返回0,不等于返回 1 或者 -1
select strcmp('hello2','hello');-- 1
# 6、截取⼀段字符串
select substr('hello',2,3);-- 字串第一个字母下标位置记为1,2代表的是第⼆个字符的位置,3代表的是截取的⻓度
# 7、将字符串进⾏反转
select reverse('hello');
# 8、将字符串中的某个字母替换为所给字母
select replace('hello','l','a');
# 9、字符串的拼接,有两种,可拼接多个字符串
# 1)使⽤某个拼接符进⾏拼接
select concat_ws(':','hello','world');
# 2) 不指定拼接符
select concat('hello','world');
# 10、数据进⾏格式化处理 最后⼀位进⾏四舍五⼊的处理
select format(3.1415926,2);
6、数学函数
# 绝对值
select abs(-1);
# 向上取整
select ceil(1.99);
#向下取整
select FLOOR(1.99);
# 除以
select 10 div 5;
select 10/5;
# 求最⼩值和最⼤值
select least(10,20,4,50,18);
select greatest(10,20,4,50,18) as 最⼤值;
# 求余数
select 5%2;
select MOD(5,2);
# 求次⽅
select POW(2,3);
# 求PI
select PI();
# 获取0到1之间的随机数,不包含1
select rand();
# eg:随机获取 [3,10)
select floor (rand() * 7 + 3 );
# 求小数点后几位,四舍五⼊
select round(1.56); -- 2
select round(1.22); -- 1
# 保留⼩数点后⼏位,不会四舍五⼊
select TRUNCATE(1.35675,3);
7、日期函数 (使用频率不是很高)
# 获取当前时间
now() ;
# 查询当前时间按年⽉⽇的形式
CURRENT_DATE();
# 按时分秒的形式
CURRENT_TIME();
# 按年⽉⽇时分秒
CURRENT_TIMESTAMP();
# 某个⽇期多少天以后(这个值可以是负数)
ADDDATE('2022-07-21',INTERVAL -10 DAY);
# 某个时间多少⼩时分钟秒之后
ADDTIME('2022-07-21 09:57:00','2:00:00');
# 获取两个时间的差值
abs(DATEDIFF('2022-07-11','2022-07-21'));
# 将数据格式化为其他的样式 %r 可以展示上午还是下午
DATE_FORMAT('2022-07-11','%y年%m⽉%d⽇');
# 获取所给时间的这个月的天数
day('2022-07-11');
# 获取所给时间的年份
YEAR('2022-07-11');
# 获取给定的⽉份
MONTH('2022-07-11');
# 该⽇期是这个⽉的第⼏天
DAYOFMONTH('2022-07-11');
# 该⽇期是这个⽉的第⼏周
DAYOFWEEK('2022-07-11'); -- 2
# 该⽇期是这一年的第⼏天
DAYOFYEAR('2022-07-11'); -- 192
# 获取当前⽇期⼀个⽉之后的⽇期,并且告知是星期⼏
DAYNAME(ADDDATE(CURRENT_DATE(),INTERVAL 1 MONTH)); -- Sunday
# 获取某个⽉的最后⼀天的⽇期
LAST_DAY(CURRENT_DATE());
# 专⻔⽤于减天数的函数
SUBDATE(now(),1);
8、其他函数
# 通过cast进⾏数据类型转换
select CAST('2022-07-21' AS DATE);
# 返回第⼀个⾮空字符串
select coalesce(null,null,'hello','world');
# 查看当前所在的数据库
select DATABASE();
select CURRENT_USER();
# 获取最后⼀个主键的id值 插入错误也算一次
select LAST_INSERT_ID();