Linux云计算训练营笔记day10(MySQL数据库)
目录
ifnull
在DQL语句中可以使用函数或表达式
函数
IFNULL(arg1,arg2)
如果arg1为NULL,函数返回arg2的值
如果arg1不为NULL,函数返回arg1的值
作用:将一个NULL值替换成一个非NULL值
NULL和任何数据运算,结果都是NULL
bash
-- 查看老师的工资和年薪分别是多少
SELECT name,salary,salary*12
from teacher;
-- 查看每个老师的工资,奖金,工资+奖金分别是多少?
SELECT name,salary,IFNULL(comm,0),salary+IFNULL(comm,0)
from teacher;
-- 查看每个老师的奖金,以及年奖金
SELECT name,IFNULL(comm,0),IFNULL(comm,0)*12
from teacher;
别名
别名
字段 as 别名
字段 as "别名"
bash
-- 查看哪些老师的年薪高于60000,并按照工资从高到低排序
SELECT name,salary*12,salary
from teacher
WHERE salary*12>60000
ORDER BY salary DESC;
SELECT name as 姓名,salary as 工资,salary*12 as 年薪
from teacher;
-- 1)当别名中有空格,必须加引号, 2)当别名中有关键字,必须加引号
SELECT name as "姓 名",salary as "from"
from teacher;
bash
-- 1.查询所有10岁学生的生日,按生日对应的年纪从大到小排序
SELECT name,birth,age
from student
WHERE age=10
ORDER BY birth ASC;
-- 2.查询8岁同学中名字含有 苗 的学生信息
SELECT name,age
from student
WHERE age=8 and name LIKE "%苗%";
-- 3.查询负责课程编号1和2号且工资高于6000的老师信息
SELECT name,subject_id,salary
from teacher
WHERE subject_id in (1,2) and salary>6000;
-- 4.查询10岁以上的语文课代表和数学课代表
SELECT name,age,job
from student
WHERE age>10 and job in ("语文课代表","数学课代表");
-- 5.查询不教 课程编号1的 老师信息,按照工资降序排序
SELECT name,subject_id,salary
from teacher
WHERE subject_id <> 1
ORDER BY salary DESC;
-- 6.查询没有奖金的老师信息 (0也属于没有奖金)
SELECT name,comm
from teacher
WHERE IFNULL(comm,0)=0;
-- 7.查询所有老师的奖金,并按照奖金降序排序
SELECT name,comm
FROM teacher
ORDER BY comm DESC;
-- 8.查看工资高于8000的老师负责的课程编号都有哪些
SELECT DISTINCT subject_id
from teacher
WHERE salary>8000;
-- 9.查看全校年龄最小学生的第6-10名 M: (页码-1)*x5 M:5 N:5
SELECT name,birth,age
from student
ORDER BY birth DESC,id
LIMIT 5,5;
聚合函数
聚合函数 将多条记录按照指定的字段进行统计并得出一个结果
MIN: 统计指定字段的最小值
MAX: 统计指定字段的最大值
AVG: 统计指定字段的平均值
SUM: 统计指定字段的总和
COUNT: 不是对字段的统计,是对记录的统计
注意事项:
聚合函数忽略NULL值
MIN MAX AVG SUM 是对值的统计,COUNT是对记录的统计
bash
-- 查看老师的平均工资是多少 (先统计老师的工资 ; 在添加聚合函数)
SELECT AVG(salary)
from teacher;
-- 查看老师的最高工资,最低工资,平均工资和工资总和是多少 (先统计参与的数据 ; 在添加聚合函数)
SELECT MAX(salary),MIN(salary),AVG(salary),SUM(salary)
from teacher;
-- 查看负责课程编号1的老师平均工资是多少 (先统计1号老师的工资 ; 在添加聚合函数)
SELECT AVG(salary)
from teacher
WHERE subject_id=1;
-- 查看一共有多少位老师
SELECT COUNT(name)
FROM teacher;
SELECT COUNT(id)
FROM teacher;
-- 统计字段共有多少条数据 (用的最多)
SELECT COUNT(*)
FROM teacher;
SELECT * from teacher;
bash
-- 1.查看所有老师的平均奖金和奖金总和是多少
SELECT AVG(IFNULL(comm,0)), SUM(comm)
from teacher;
-- 2.查看负责课程编号2的老师共有多少人
SELECT COUNT(*)
from teacher
WHERE subject_id=2;
-- 3.查看班级编号为 1 的学生有多少人
SELECT COUNT(*)
FROM student
WHERE class_id=1;
-- 4.查看全校学生 生日 最大的是哪天
SELECT MIN(birth)
from student;
-- 5.查看11岁的课代表总共有多少人
SELECT COUNT(*)
from student
WHERE age=11 and job LIKE "%课代表";
-- 6.姓 张 的学生有多少人
SELECT COUNT(*)
from student
WHERE name LIKE "张%";
-- 7.工资高于5000的老师中最低的工资是多少
SELECT MIN(salary)
from teacher
WHERE salary>5000;
-- 8.4层有几个班
SELECT COUNT(*)
from class
WHERE floor=4;
-- 9.老师中 总监 的平均工资是多少
SELECT AVG(salary)
from teacher
WHERE title="总监";
group by
group by
对结果集按照指定字段相同的记录进行分组,配合聚合函数做到组内统计
group by一定是配合聚合函数的,如果select子句没有聚合函数,不会使用group by
在select语句中凡是不在聚合函数中的字段都应出现在group by子句中
group by可以按照多组字段分组,那些字段值相同的记录被看做一组
把结果集按照聚合函数的统计结果排序
bash
-- 查看每种职位 title 的老师平均工资是多少 (title字段值相同的记录会被划分为一组)
SELECT AVG(salary),title
from teacher
GROUP BY title;
-- 查看每个班级各有多少人 (class_id字段值相同的学生是一个班)
SELECT COUNT(*),class_id
from student
GROUP BY class_id;
-- 查看学生每种 职位各有多少人,以及最大生日和最小生日
SELECT COUNT(*) as 人数, MIN(birth) as 最大生日,MAX(birth) as 最小生日, job as 职位
from student
GROUP BY job;
-- 查看同班级 同性别的学生有多少人
SELECT COUNT(*),class_id,gender
FROM student
GROUP BY class_id,gender;
-- 查看每个班级 每种职位各有多少人
SELECT COUNT(*) as 人数,class_id,job
from student
GROUP BY class_id,job;
-- 查看每个科目老师的平均工资排名
SELECT AVG(salary) as 平均工资,subject_id
from teacher
GROUP BY subject_id
ORDER BY AVG(salary) DESC;
HAVING
HAVING
在group by之后,用于添加条件过滤分组的
聚合函数不能出现在where子句中
HAVING和WHERE
1)过滤时机不同,WHERE先过滤,HAVING后过滤
2)WHERE用于确定结果集的记录
3)HAVING用于确定保留哪些分组
4)WHERE不可以使用聚合函数作为过滤条件,HAVING可以
bash
- 查询每个科目老师的平均工资,但是只看平均工资高于6000的那些
SELECT AVG(salary),subject_id
from teacher
GROUP BY subject_id
HAVING AVG(salary) >6000;
-- 查询每个科目老师的平均工资,前提是该科目老师最高工资要超过9000
SELECT AVG(salary),MAX(salary),subject_id
from teacher
GROUP BY subject_id
HAVING MAX(salary)>9000;
bash
-- 1.查看科目老师的工资总和是多少,前提是该科老师的平均奖金要高于4000
SELECT SUM(salary),subject_id
from teacher
GROUP BY subject_id
HAVING AVG(comm)>4000;
-- 2.查看各科目 男老师 的平均工资是多少,前提是该科目老师最低工资高于4000
SELECT AVG(salary),subject_id
from teacher
WHERE gender="男"
GROUP BY subject_id
HAVING MIN(salary)>4000;
-- 3.查看班级编号小于6的每个班 各有多少人
SELECT COUNT(*), class_id
from student
WHERE class_id<6
GROUP BY class_id;
-- 4.查看3层一共多少个班
SELECT COUNT(*)
from class
WHERE floor=3;
-- 5.查看工资低于8000的老师的平均工资是多少
SELECT AVG(salary)
from teacher
WHERE salary<8000;
-- 6.查看班级人数超过60人的班级中年级最大的同学生日是多少
SELECT MIN(birth), class_id
from student
GROUP BY class_id
HAVING COUNT(*)>60;
-- 7.查看教课程编号1 的老师平均年龄是多少
SELECT AVG(age)
from teacher
WHERE subject_id=1;
-- 8.查看同一科目平均年龄超过35岁的 老师中最小年龄是多少
SELECT MIN(age),subject_id
from teacher
GROUP BY subject_id
HAVING AVG(age)>35;
-- 9.查看同职称人数超过 4人的老师 的平均工资是多少
SELECT AVG(salary),title
from teacher
GROUP BY title
HAVING COUNT(*)>4;
子查询
子查询
嵌套在其他SQL语句中的一条DQL语句
在DQL中使用
在select子句中使用,将该查询结果当做一个字段列在外层查询的结果集中
在DML中使用
在增删改中,基于该查询结果集对表中数据进行操作
子查询的分类
1)单行单列子查询
2)单行多列子查询
可以同时查询出多个值
如果进行等值判断 in,not in
如果进行关系运算
>ANY(列表) 大于列表中最小的值
<ANY(列表) 小于列表中最大的值
>ALL(列表) 大于列表中所有值 >最大的
<ALL(列表) 小于列表中所有值 <最小的
3)多列子查询
bash
-- 查看比范传奇工资高的老师都有谁
-- 1)范传奇的工资是多少 - 3000
SELECT salary from teacher WHERE name="范传奇";
-- 2)查看谁的工资高于3000
SELECT name,salary from teacher where salary>3000;
SELECT name,salary
from teacher
WHERE salary>(SELECT salary from teacher WHERE name="范传奇");
-- 查看哪些老师的工资是高于平均工资的
-- 平均工资是多少 - 6355.050
SELECT AVG(salary) from teacher;
-- 查看高于平均工资的
SELECT name,salary from teacher WHERE salary>6355.050;
SELECT name,salary
from teacher
WHERE salary>(SELECT AVG(salary) from teacher);
-- 查看和 李费水 在同一个班级的学生都有谁
-- 李费水的班级编号
SELECT class_id from student WHERE name="李费水";
SELECT name,class_id
from student
WHERE class_id=(SELECT class_id from student WHERE name="李费水");
-- 查看 3年级2班 在同一层的班级都有哪些,列出班级编号,名字,楼层
SELECT floor from class WHERE name="3年级2班";
SELECT id,name,floor
from class
WHERE floor=(SELECT floor from class WHERE name="3年级2班");
-- 查看3年级2班的学生都有谁
SELECT id from class WHERE name="3年级2班";
SELECT name,class_id
from student
WHERE class_id=(SELECT id from class WHERE name="3年级2班");
-- 查看教语文的老师都有谁
select id from subject WHERE name="语文";
SELECT name,subject_id
from teacher
WHERE subject_id=(select id from subject WHERE name="语文");
-- 查看工资最高的老师的工资和奖金是多少
select MAX(salary) from teacher;
SELECT name,salary,comm
from teacher
WHERE salary=(select MAX(salary) from teacher);
-- 查看和 祝雷 李费水 在同一个班的学生都有谁
SELECT class_id from student WHERE name in ("祝雷","李费水");
SELECT name,class_id
from student
WHERE class_id in (SELECT class_id from student WHERE name in ("祝雷","李费水"));
-- 查看不与 范传奇 和 王克晶 教同一课的老师都有谁
SELECT name,subject_id
from teacher
WHERE subject_id not in (SELECT subject_id from teacher WHERE name in ("范传奇","王克晶"));
-- 查看比教 科目2 和 科目4 老师工资都高的老师都有谁
SELECT salary from teacher WHERE subject_id in (2,4);
SELECT name,salary
from teacher
WHERE salary>ALL(SELECT salary from teacher WHERE subject_id in (2,4));
-- 给与 范传奇 负责同一科目的所有老师工资涨1000
UPDATE teacher set salary=salary+1000
WHERE subject_id=(SELECT subject_id from teacher WHERE name="范传奇");
-- 将王克晶 的工资改成与 范传奇一样
UPDATE teacher
SET salary=(SELECT salary from teacher WHERE name="范传奇")
WHERE name="王克晶";
关联查询
关联查询
联合多张表查询数据,结果来自于多张表
关系的分类
1)一对一关系: 一个表的记录对应另一个表的记录
用户表 用户详情表
create table user(
id int primary key auto_increment,
name varchar(10)
);
create table user_detail(
user_id int primary key auto_increment,
address varchar(10),
foreign key(user_id) references user(id);
)
- 一对多关系
主表的一条记录 对应另外一张表的多条数据
部门表 员工表
create table dept(
id int primary key auto_increment,
name varchar(10)
);
create table emp(
id int primary key auto_increment,
name varchar(10),
deptId int,
foreign key(deptId) references dept(id);
)
3)多对多关系
两个表的记录可以相互对应多条数据
学生表 课程表 (通过中间表实现)
create table student(
id int primary key auto_increment,
name varchar(10)
);
create table courses(
id int primary key auto_increment,
name varchar(10)
);
create table student_courses(
student_id int,
couses_id int,
primary key(student_id,couses_id),
foreign key(student_id) references student(id),
foreign key(couses_id) references courses(id);
);
连接条件 用于关联两张表中数据对应关系
在关联查询中通常两张表要指定连接条件,否则会产生笛卡尔积.
笛卡尔积的查询结果是两张表的 乘积
bash
-- 查看每个老师的名字和其所教科目的名字
SELECT teacher.name,teacher.salary,teacher.age,subject.name
from teacher,subject
WHERE teacher.subject_id=subject.id;
SELECT t.name,t.salary,t.age,s.name
from teacher t,subject s
WHERE t.subject_id=s.id;
SELECT * from teacher;
SELECT * from subject;
show tables;
desc teacher;
desc subject;
SELECT t.name,t.salary,t.age,s.name
from teacher t,subject s;
-- 查看班级的名称和对应的班主任老师是谁
SELECT c.name,c.teacher_id,t.name,t.id
from class c,teacher t
WHERE c.teacher_id=t.id;
-- 查看每个学生的名字 年龄 以及其所在的班级名称和所在楼层
SELECT s.name,s.age,c.name,c.floor
from student s,class c
WHERE s.class_id=c.id;
-- 查看每个学生来自哪座城市的名字,列出学生的名字,性别,年龄和所在城市的名字
select s.name,s.gender,s.age,l.name
from student s, location l
WHERE s.location_id=l.id;
-- 王克晶 是哪个班的班主任?列出 班级名称 楼层 老师名称 工资
SELECT c.name,c.floor,t.name,t.salary
from class c,teacher t
WHERE t.id=c.teacher_id and t.name="王克晶";
-- 查看三年级的班主任都是谁,要列出 班级名称,所在楼层,班主任名字 工资
SELECT c.name,c.floor,t.name,t.salary
from class c,teacher t
WHERE c.teacher_id=t.id and c.name LIKE "3年级%";