上节回顾:
mysql停止的流程,多实例在不知root密码情况下通过命令行是否能停止
sql语句在查询不到数据时的执行流程如何手动停止手动开启的数据库;如何从8.0降级到5.7
mysqladmin -uroot -p -S /tmp/xxx shutdown
3.配合多子句
select from where group by
where
=
< >= <=
like 'aaa%'
and or in
between and
group by + 聚合函数
一张大表中,需要对具有共同条件的数据,进行分组统计工作.
max()
min()
count()
sum()
avg()
group_concat
显示表数据时,不能1对多的显示,5.7中通过sql_mode=ONLY_fULL_GROUP_BY
====================================
from where group by having order by limit
- having 后过滤
--- 统计中国每个省的总人口数,只显示总人口大于500w
SELECT district , SUM(population)
FROM city
WHERE countrycode='CHN'
GROUP BY district
HAVING SUM(population)>5000000;
- order by
--- 查询中国所有的城市信息,并按照人口数排序输出结果
SELECT * FROM city
WHERE countrycode='CHN'
ORDER BY population DESC ;
--- 统计中国每个省的总人口数,只显示总人口大于500w,并按照总人口降序输出
SELECT district , SUM(population)
FROM city
WHERE countrycode='CHN'
GROUP BY district
HAVING SUM(population)>5000000
ORDER BY SUM(population) DESC ;
- LIMIT
--- 统计中国每个省的总人口数,只显示总人口大于500w,并按照总人口降序输出前5名
SELECT district , SUM(population)
FROM city
WHERE countrycode='CHN'
GROUP BY district
HAVING SUM(population)>5000000
ORDER BY SUM(population) DESC
LIMIT 10;
SELECT district , SUM(population)
FROM city
WHERE countrycode='CHN'
GROUP BY district
HAVING SUM(population)>5000000
ORDER BY SUM(population) DESC
LIMIT 2,3;
SELECT district , SUM(population)
FROM city
WHERE countrycode='CHN'
GROUP BY district
HAVING SUM(population)>5000000
ORDER BY SUM(population) DESC
LIMIT 4 OFFSET 2;
distinct 去重复
mysql> select distinct countrycode from city ;union && union all
SELECT * FROM city WHERE countrycode='CHN' OR countrycode='USA';
SELECT * FROM city WHERE countrycode IN ('CHN' ,'USA');
SELECT * FROM city WHERE countrycode='CHN'
UNION ALL
SELECT * FROM city WHERE countrycode='USA';
union : 去重复
union all : 不去重复
======================
- 多表连接查询
7.0 多表连接准备
按需求创建一下表结构:
use school
student :学生表
sno: 学号
sname:学生姓名
sage: 学生年龄
ssex: 学生性别
teacher :教师表
tno: 教师编号
tname:教师名字
course :课程表
cno: 课程编号
cname:课程名字
tno: 教师编号
score :成绩表
sno: 学号
cno: 课程编号
score:成绩
============================================
CREATE DATABASE school CHARSET utf8;
USE school
CREATE TABLE student(
sno INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '学号',
sname VARCHAR(20) NOT NULL COMMENT '姓名',
sage TINYINT UNSIGNED NOT NULL COMMENT '年龄',
ssex ENUM('f','m') NOT NULL DEFAULT 'm' COMMENT '性别'
)ENGINE=INNODB CHARSET=utf8;
CREATE TABLE course(
cno INT NOT NULL PRIMARY KEY COMMENT '课程编号',
cname VARCHAR(20) NOT NULL COMMENT '课程名字',
tno INT NOT NULL COMMENT '教师编号'
)ENGINE=INNODB CHARSET utf8;
CREATE TABLE sc (
sno INT NOT NULL COMMENT '学号',
cno INT NOT NULL COMMENT '课程编号',
score INT NOT NULL DEFAULT 0 COMMENT '成绩'
)ENGINE=INNODB CHARSET=utf8;
CREATE TABLE teacher(
tno INT NOT NULL PRIMARY KEY COMMENT '教师编号',
tname VARCHAR(20) NOT NULL COMMENT '教师名字'
)ENGINE=INNODB CHARSET utf8;
INSERT INTO student(sno,sname,sage,ssex)
VALUES
(1,'zhang3',18,'m'),
(2,'zhang4',18,'m'),
(3,'li4',18,'m'),
(4,'wang5',19,'f'),
(5,'zh4',18,'m'),
(6,'zhao4',18,'m'),
(7,'ma6',19,'f');
(8,'oldboy',20,'m'),
(9,'oldgirl',20,'f'),
(10,'oldp',25,'m');
INSERT INTO teacher(tno,tname) VALUES
(101,'oldboy'),
(102,'hesw'),
(103,'oldguo');
INSERT INTO course(cno,cname,tno)
VALUES
(1001,'linux',101),
(1002,'python',102),
(1003,'mysql',103);
INSERT INTO sc(sno,cno,score)
VALUES
(1,1001,80),
(1,1002,59),
(2,1002,90),
(2,1003,100),
(3,1001,99),
(3,1003,40),
(4,1001,79),
(4,1002,61),
(4,1003,99),
(5,1003,40),
(6,1001,89),
(6,1003,77),
(7,1001,67),
(7,1003,82),
(8,1001,70),
(9,1003,80),
(10,1003,96);
SELECT * FROM student;
SELECT * FROM teacher;
SELECT * FROM course;
SELECT * FROM sc;
===============
7.1 多表连接应用
-- 查询人口数量少于100人的城市信息
SELECT * FROM world.city WHERE population<100;
-- 延伸一下: 查询人口数量少于100人的城市名,人口数,国家名,国土面积
SELECT
city.name,
city.population,
country.name,
country.surfacearea
FROM city
JOIN country
ON city.countrycode=country.code
WHERE city.population<100;
说明:
1. 通过查询需求,找到所需表
2. 找到所有表之间的关联关系
语法:
两表关联:
from a join b on a.x=b.y
多表关联:
from a
join c on a.x=c.y
join b on c.z=b.z
例子:
-- 1. 每位老师讲的课程名称
SELECT teacher.tno,teacher.tname,GROUP_CONCAT(course.cname)
FROM teacher
JOIN course
ON teacher.tno=course.tno
GROUP BY teacher.tno;
思考: 如果老师名重名,或者老师讲多门课,怎么办?
-- 2. 每位学员学习了几门课?
SELECT student.sno,student.sname,COUNT(sc.cno)
FROM student
JOIN sc
ON student.sno=sc.sno
GROUP BY student.sno;
-- 3. 每位学员学习了几门课及课程名称列表?
SELECT
student.sno,
student.sname,
COUNT(sc.cno),
GROUP_CONCAT(course.cname)
FROM student
JOIN sc
ON student.sno=sc.sno
JOIN course
ON sc.cno=course.cno
GROUP BY student.sno;
张启
-- 5. 查询每位老师所教学生的人数及姓名
select teacher.tname,group_concat(student.sname),count(student.sname)
from teacher
join course
on teacher.tno = course.tno
join sc
on sc.cno = course.cno
join student
on student.sno = sc.sno
group by teacher.tno;
-- 6. 统计每位老师所教课程的平均分
select teacher.tname,group_concat(course.cname),avg(sc.score)
from teacher
join course
on teacher.tno = course.tno
join sc
on sc.cno = course.cno
group by teacher.tno;
王凯鹏:
-- 7. 统计每位老师所教课程不及格的学生名
select teacher.tname,group_concat(student.sname)
from teacher
join course
on teacher.tno = course.tno
join sc
on sc.cno = course.cno
join student
on student.sno = sc.sno
where sc.score < 60
group by teacher.tno;
-- 8. 查询平均成绩大于60分的同学的学号和平均成绩;
select student.sno, avg(sc.score)
from student
join sc
on student.sno = sc.sno
group by student.sno
having avg(sc.score) > 60;
陈娇娜 1
-- 9. 查询所有同学的学号、姓名、选课数、总成绩;
select student.sno,student.sname,count(course.cno),sum(sc.score)
from student join sc on student.sno=sc.sno
join course on sc.cno=course.cno
group by student.sno;
-- 10. 查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
select course.cno,max(sc.score),min(sc.score)
from course join sc on course.cno=sc.cno
group by course.cno;
杨腾
-- 11. 查询每门课程被选修的学生数
select course.cname,count(student.sno)
from sc
on
jion couse
on
join student
group by course.cno
-- 12. 查询出只选修了一门课程的全部学生的学号和姓名
select student.sno,student.sname
from student
sc
group by sutdent.sno
having count(sc.cno)=1;
荆俊玮
-- 13. 查询选修课程门数超过1门的学生信息
select student.sno,student.sname,****
from student
sc
group by sutdent.sno
having count(sc.cno)>1
-- 15. 查询平均成绩大于85的所有学生的学号、姓名和平均成绩
select student.sno,student.sname,avg(sc.score)
from student
sc
group by sutdent.sno
having avg(sc.score)>85
扩展:
-- 16. -- 50
统计每门课程:
优秀(85分以上),
良好(70-85),
一般(60-70),
不及格(小于60)的学生列表
select 课程名 , 优秀 , 良好 , 一般 , 不及格
-- 17. -- 50 张现伟
统计各位老师,所教课程的及格率
select teacher.tno,course.cname,concat(count(case when sc.score>60 then 1 end)/count(sc.score)*100,"%") as "啊啊啊" from teacher join course on teacher.tno=course.tno join sc on course.cno=sc.cno group by teacher.tno,course.cno;
考试题:
https://www.jianshu.com/p/c99e2d3d295b
==============================================
写多表连接技巧
- 相关表
- 找相关表关联条件
E-R 图 (自己扩展) ----> 开发DBA要做的事情
外连接
A left join B
A 表所有的数据+B表满足关联条件的数据
A right join B
B表所有的数据+A 满足关联条件的数据
实现外连接原生功能,需要把where的条件改为and/
mysql> select city.name,city.population ,country.name from city left join country on city.countrycode=country.code and city.population<100 order by population desc ;
结论: left join 应用场景,强制驱动表(关联查询中结果集小的)
- where 条件
- 原始表大小
- 别名的应用
表别名: 给表设计的别名,在任何子句中调用
列别名: 给select 后的列设定别名,在having 和 order by子句中调用
表别名:
select a.tname AS "老师姓名" ,group_concat(d.sname) AS "不及格的学生"
from teacher AS a
join course AS b
on a.tno = b.tno
join sc AS c
on c.cno = b.cno
join student AS d
on d.sno = c.sno
where c.score < 60
group by a.tno;
列别名:
select
student.sno AS 学生学号 ,
student.sname AS 学生姓名,
avg(sc.score) AS 平均成绩
from student
join sc
on student.sno=sc.sno
group by sutdent.sno
having 平均成绩 >85
==================
子查询 : (自己了解)
高级SQL编程: 内置函数,存储过程,函数,视图,事件,触发器,游标,Json开发 (自己了解)
==================
- show 语句
show databases ; 查看所有库名
show tables; 查看当前库下的所有表名.
show tables from world; 查看world库下的所有表
show create database world; 查看建库语句
show create tables city; 查看建表语句
show [global] variables like '%trx%'; 查看参数信息
show grants for root@'localhost'; 查看用户权限信息
show [full] processlist; 查看会话连接情况
show engines; 查看当前数据库支持的引擎.
show charset; 查看当前数据库支持的字符集.
show collation; 查看当前数据库支持的排序规则.
show [global] status; 查看当前数据库的状态信息.
show status like '%lock%'\G 模糊查询数据库状态.
show master status; 查看当前使用的二进制日志信息.
show binary logs; 查看所有二进制日志信息.
show binlog evnets in 'xxxx' 查看二进制日志事件信息.
show relaylog events in 'xxx' 查看中继日志事件信息.
show slave status \G 查看从库复制状态信息.
show engine innodb status \G 查看InnoDB引擎相关状态信息.
======================
- 元数据获取
10.1 什么是元数据?
库,表 : 属性(字符集,校对规则,数据类型,存储引擎,约束,其他数据)
权限 :
状态信息:
等.
10.2 元数据获取方法
show语句 : 封装好的基础功能,可以实现大部分的元数据查询需求.
information_schema<视图>库: mysql 给我们定义好的元数据查询的方法.
10.3 information_schema<视图>库
应用场景: 做数据库资产统计.
tables :
TABLE_SCHEMA : 表所在的库
TABLE_NAME : 表名
ENGINE : 引擎
TABLE_ROWS : 表的行数
AVG_ROW_LENGTH: 平均行长度
INDEX_LENGTH : 索引长度
TABLE_COMMENT : 表的注释
例子:
-- 1. 统计所有库下的表的个数
select table_schema,count(table_name) from information_schema.tables group by table_schema;
-- 2. 统计不同存储引擎的表名
select engine,group_concat(table_name) from information_schema.tables group by engine;
-- 3. 统计所有非系统表,非InnoDB的表
mysql
information_schema
performace_schema
sys
SELECT table_schema,table_name ,ENGINE
FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys')
HAVING ENGINE != 'innodb';