更正文档中的问题和笔误
parent
558049fd0d
commit
965af7c53f
|
@ -1,4 +1,4 @@
|
||||||
## 第18课:面向对象编程应用
|
## 第19课:面向对象编程应用
|
||||||
|
|
||||||
面向对象编程对初学者来说不难理解但很难应用,虽然我们为大家总结过面向对象的三步走方法(定义类、创建对象、给对象发消息),但是说起来容易做起来难。**大量的编程练习**和**阅读优质的代码**可能是这个阶段最能够帮助到大家的两件事情。接下来我们还是通过经典的案例来剖析面向对象编程的知识,同时也通过这些案例为大家讲解如何运用之前学过的Python知识。
|
面向对象编程对初学者来说不难理解但很难应用,虽然我们为大家总结过面向对象的三步走方法(定义类、创建对象、给对象发消息),但是说起来容易做起来难。**大量的编程练习**和**阅读优质的代码**可能是这个阶段最能够帮助到大家的两件事情。接下来我们还是通过经典的案例来剖析面向对象编程的知识,同时也通过这些案例为大家讲解如何运用之前学过的Python知识。
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## SQL详解之DDL
|
## 第41课:SQL详解之DDL
|
||||||
|
|
||||||
我们通常可以将 SQL 分为四类,分别是 DDL(数据定义语言)、DML(数据操作语言)、DQL(数据查询语言)和 DCL(数据控制语言)。DDL 主要用于创建、删除、修改数据库中的对象,比如创建、删除和修改二维表,核心的关键字包括`create`、`drop`和`alter`;DML 主要负责数据的插入、删除和更新,关键词包括`insert`、`delete`和`update`;DQL 负责数据查询,最重要的一个关键词是`select`;DCL 通常用于授予和召回权限,核心关键词是`grant`和`revoke`。
|
我们通常可以将 SQL 分为四类,分别是 DDL(数据定义语言)、DML(数据操作语言)、DQL(数据查询语言)和 DCL(数据控制语言)。DDL 主要用于创建、删除、修改数据库中的对象,比如创建、删除和修改二维表,核心的关键字包括`create`、`drop`和`alter`;DML 主要负责数据的插入、删除和更新,关键词包括`insert`、`delete`和`update`;DQL 负责数据查询,最重要的一个关键词是`select`;DCL 通常用于授予和召回权限,核心关键词是`grant`和`revoke`。
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## SQL详解之DML
|
## 第42课:SQL详解之DML
|
||||||
|
|
||||||
我们接着上一课中创建的学校选课系统数据库,为大家讲解 DML 的使用。DML 可以帮助将数据插入到二维表(`insert`操作)、从二维表删除数据(`delete`操作)以及更新二维表的数据(`update`操作)。在执行 DML 之前,我们先通过下面的`use`命令切换到`school`数据库。
|
我们接着上一课中创建的学校选课系统数据库,为大家讲解 DML 的使用。DML 可以帮助将数据插入到二维表(`insert`操作)、从二维表删除数据(`delete`操作)以及更新二维表的数据(`update`操作)。在执行 DML 之前,我们先通过下面的`use`命令切换到`school`数据库。
|
||||||
|
|
||||||
|
|
|
@ -1,370 +1,415 @@
|
||||||
## SQL详解之DQL
|
## 第43课:SQL详解之DQL
|
||||||
|
|
||||||
接下来,我们利用之前创建的学校选课系统数据库,为大家讲解 DQL 的应用。无论对于开发人员还是数据分析师,DQL 都是非常重要的,它关系着我们能否从关系数据库中获取我们需要的数据。建议大家把上上一节课中建库建表的 DDL 以及 上一节课中插入数据的 DML 重新执行一次,确保表和数据跟没有问题再执行下面的操作。
|
接下来,我们利用之前创建的学校选课系统数据库,为大家讲解 DQL 的应用。无论对于开发人员还是数据分析师,DQL 都是非常重要的,它关系着我们能否从关系数据库中获取我们需要的数据。建议大家把上上一节课中建库建表的 DDL 以及 上一节课中插入数据的 DML 重新执行一次,确保表和数据跟没有问题再执行下面的操作。
|
||||||
|
|
||||||
```SQL
|
```SQL
|
||||||
use `school`;
|
use `school`;
|
||||||
|
|
||||||
-- 查询所有学生的所有信息
|
-- 01. 查询所有学生的所有信息
|
||||||
-- 说明:实际工作中不建议使用 select * 的方式进行查询
|
select *
|
||||||
select *
|
from tb_student;
|
||||||
from tb_student;
|
|
||||||
|
|
||||||
-- 查询学生的学号、姓名和籍贯
|
|
||||||
select stu_id,
|
|
||||||
stu_name,
|
|
||||||
stu_addr
|
|
||||||
from tb_student;
|
|
||||||
|
|
||||||
select stu_id as 学号,
|
select stu_id
|
||||||
stu_name as 姓名,
|
, stu_name
|
||||||
stu_addr as 籍贯
|
, stu_sex
|
||||||
from tb_student;
|
, stu_birth
|
||||||
|
, stu_addr
|
||||||
|
, col_id
|
||||||
|
from tb_student;
|
||||||
|
|
||||||
-- 查询所有课程的名称及学分
|
-- 02. 查询学生的学号、姓名和籍贯(投影和别名)
|
||||||
select cou_name as 课程名称,
|
select stu_id as 学号
|
||||||
cou_credit as 学分
|
, stu_name as 姓名
|
||||||
from tb_course;
|
, stu_addr as 籍贯
|
||||||
|
from tb_student;
|
||||||
|
|
||||||
-- 查询所有女学生的姓名和出生日期
|
-- 03. 查询所有课程的名称及学分(投影和别名)
|
||||||
select stu_name,
|
select cou_name as 课程名称
|
||||||
stu_birth
|
, cou_credit as 学分
|
||||||
from tb_student
|
from tb_course;
|
||||||
where stu_sex=0;
|
|
||||||
|
|
||||||
-- 查询籍贯为“四川成都”的女学生的姓名和出生日期
|
-- 04. 查询所有女学生的姓名和出生日期(数据筛选)
|
||||||
select stu_name,
|
select stu_name
|
||||||
stu_birth
|
, stu_birth
|
||||||
from tb_student
|
from tb_student
|
||||||
where stu_sex=0
|
where stu_sex = 0;
|
||||||
and stu_addr='四川成都';
|
|
||||||
|
|
||||||
-- 查询籍贯为“四川成都”或者性别是女的学生
|
-- 05. 查询籍贯为“四川成都”的女学生的姓名和出生日期(数据筛选)
|
||||||
select stu_name,
|
select stu_name
|
||||||
stu_birth
|
, stu_birth
|
||||||
from tb_student
|
from tb_student
|
||||||
where stu_sex=0
|
where stu_sex = 0 and stu_addr = '四川成都';
|
||||||
or stu_addr='四川成都';
|
|
||||||
|
|
||||||
-- 查询所有80后学生的姓名、性别和出生日期
|
-- 06. 查询籍贯为“四川成都”或者性别是女的学生(数据筛选)
|
||||||
-- 方法一:
|
select stu_name
|
||||||
select stu_name,
|
, stu_birth
|
||||||
stu_sex,
|
from tb_student
|
||||||
stu_birth
|
where stu_sex = 0 or stu_addr = '四川成都';
|
||||||
from tb_student
|
|
||||||
where stu_birth >= '1980-1-1'
|
|
||||||
and stu_birth <= '1989-12-31';
|
|
||||||
|
|
||||||
-- 方法二:
|
-- 07. 查询所有80后学生的姓名、性别和出生日期(数据筛选)
|
||||||
select stu_name,
|
select stu_name
|
||||||
stu_sex,
|
, stu_sex
|
||||||
stu_birth
|
, stu_birth
|
||||||
from tb_student
|
from tb_student
|
||||||
where stu_birth between '1980-1-1' and '1989-12-31';
|
where '1980-1-1' <= stu_birth and stu_birth <= '1989-12-31';
|
||||||
|
|
||||||
-- 查询学分大于2的课程的名称和学分
|
|
||||||
select cou_name,
|
|
||||||
cou_credit
|
|
||||||
from tb_course
|
|
||||||
where cou_credit > 2;
|
|
||||||
|
|
||||||
-- 查询学分是奇数的课程的名称和学分
|
|
||||||
select cou_name,
|
|
||||||
cou_credit
|
|
||||||
from tb_course
|
|
||||||
where cou_credit % 2 <> 0;
|
|
||||||
|
|
||||||
-- 查询选择选了1111的课程考试成绩在90分以上的学生学号
|
|
||||||
select stu_id
|
|
||||||
from tb_record
|
|
||||||
where cou_id = 1111
|
|
||||||
and score > 90;
|
|
||||||
|
|
||||||
-- 查询姓“杨”的学生姓名和性别(模糊)
|
select stu_name
|
||||||
-- % 可以匹配零个或任意多个字符
|
, stu_sex
|
||||||
select stu_name,
|
, stu_birth
|
||||||
stu_sex
|
from tb_student
|
||||||
from tb_student
|
where stu_birth between '1980-1-1' and '1989-12-31';
|
||||||
where stu_name like '杨%';
|
|
||||||
|
|
||||||
-- 查询姓“杨”名字两个字的学生姓名和性别(模糊)
|
-- MySQL方言
|
||||||
-- _ 可以匹配一个字符
|
select stu_name
|
||||||
select stu_name,
|
, if(stu_sex, '男', '女') as stu_sex
|
||||||
stu_sex
|
, stu_birth
|
||||||
from tb_student
|
from tb_student
|
||||||
where stu_name like '杨_';
|
where stu_birth between '1980-1-1' and '1989-12-31';
|
||||||
|
|
||||||
-- 查询姓“杨”名字三个字的学生姓名和性别(模糊)
|
select stu_name
|
||||||
select stu_name,
|
, case stu_sex
|
||||||
stu_sex
|
when 1 then '男'
|
||||||
from tb_student
|
else '女'
|
||||||
where stu_name like '杨__';
|
end as stu_sex
|
||||||
|
, stu_birth
|
||||||
|
from tb_student
|
||||||
|
where stu_birth between '1980-1-1' and '1989-12-31';
|
||||||
|
|
||||||
-- 查询名字中有“不”字或“嫣”字的学生的姓名(模糊)
|
-- 08. 查询学分大于2分的课程名称和学分(数据筛选)
|
||||||
-- 方法一:
|
select cou_name
|
||||||
select stu_name,
|
, cou_credit
|
||||||
stu_sex
|
from tb_course
|
||||||
from tb_student
|
where cou_credit > 2;
|
||||||
where stu_name like '%不%'
|
|
||||||
or stu_name like '%嫣%';
|
|
||||||
|
|
||||||
-- 方法二:
|
-- 09. 查询学分是奇数的课程的名称和学分(数据筛选)
|
||||||
select stu_name,
|
select cou_name
|
||||||
stu_sex
|
, cou_credit
|
||||||
from tb_student
|
from tb_course
|
||||||
where stu_name like '%不%'
|
where cou_credit mod 2 <> 0;
|
||||||
|
|
||||||
|
-- 10. 查询选择选了1111的课程考试成绩在90分以上的学生学号(数据筛选)
|
||||||
|
select stu_id
|
||||||
|
from tb_record
|
||||||
|
where cou_id = 1111 and score > 90;
|
||||||
|
|
||||||
|
-- 11. 查询名字叫“杨过”的学生的姓名和性别
|
||||||
|
select stu_name
|
||||||
|
, stu_sex
|
||||||
|
from tb_student
|
||||||
|
where stu_name = '杨过';
|
||||||
|
|
||||||
|
-- 12. 查询姓“杨”的学生姓名和性别(模糊查询)
|
||||||
|
-- wild card - 通配符 - % - 代表零个或任意多个字符
|
||||||
|
select stu_name
|
||||||
|
, stu_sex
|
||||||
|
from tb_student
|
||||||
|
where stu_name like '杨%';
|
||||||
|
|
||||||
|
-- 13. 查询姓“杨”名字两个字的学生姓名和性别(模糊查询)
|
||||||
|
-- wild card - 通配符 - _ - 精确匹配一个字符
|
||||||
|
select stu_name
|
||||||
|
, stu_sex
|
||||||
|
from tb_student
|
||||||
|
where stu_name like '杨_';
|
||||||
|
|
||||||
|
-- 14. 查询姓“杨”名字三个字的学生姓名和性别(模糊查询)
|
||||||
|
select stu_name
|
||||||
|
, stu_sex
|
||||||
|
from tb_student
|
||||||
|
where stu_name like '杨__';
|
||||||
|
|
||||||
|
-- 15. 查询名字中有“不”字或“嫣”字的学生的姓名(模糊查询)
|
||||||
|
select stu_name
|
||||||
|
from tb_student
|
||||||
|
where stu_name like '%不%' or stu_name like '%嫣%';
|
||||||
|
|
||||||
|
select stu_name
|
||||||
|
from tb_student
|
||||||
|
where stu_name like '%不%'
|
||||||
union
|
union
|
||||||
select stu_name,
|
select stu_name
|
||||||
stu_sex
|
from tb_student
|
||||||
from tb_student
|
where stu_name like '%嫣%';
|
||||||
where stu_name like '%嫣%';
|
|
||||||
|
|
||||||
-- 查询姓“杨”或姓“林”名字三个字的学生的姓名
|
|
||||||
select stu_name,
|
|
||||||
stu_sex
|
|
||||||
from tb_student
|
|
||||||
where stu_name regexp '^[杨林][\\u4e00-\\u9fa5]{2}$';
|
|
||||||
|
|
||||||
-- 查询没有录入籍贯的学生姓名
|
|
||||||
select stu_name
|
|
||||||
from tb_student
|
|
||||||
where stu_addr = ''
|
|
||||||
or stu_addr is null;
|
|
||||||
|
|
||||||
-- 查询录入了籍贯的学生姓名
|
|
||||||
select stu_name
|
|
||||||
from tb_student
|
|
||||||
where stu_addr <> ''
|
|
||||||
and stu_addr is not null;
|
|
||||||
|
|
||||||
-- 查询学生选课的所有日期
|
|
||||||
select distinct sel_date
|
|
||||||
from tb_record;
|
|
||||||
|
|
||||||
-- 查询学生的籍贯
|
|
||||||
select distinct stu_addr
|
|
||||||
from tb_student
|
|
||||||
where stu_addr <> ''
|
|
||||||
and stu_addr is not null;
|
|
||||||
|
|
||||||
-- 查询学院编号为1的学生姓名、性别和生日按年龄从大到小排列
|
|
||||||
-- asc - 升序(从小到大,默认),desc - 降序(从大到小)
|
|
||||||
select stu_name,
|
|
||||||
stu_sex,
|
|
||||||
stu_birth
|
|
||||||
from tb_student
|
|
||||||
where col_id = 1
|
|
||||||
order by stu_sex asc,
|
|
||||||
stu_birth asc;
|
|
||||||
|
|
||||||
-- 补充:将上面的性别处理成“男”或“女”,将生日换算成年龄
|
|
||||||
select stu_name as 姓名,
|
|
||||||
if(stu_sex, '男', '女') as 性别,
|
|
||||||
floor(datediff(curdate(), stu_birth) / 365) as 年龄
|
|
||||||
from tb_student
|
|
||||||
where col_id = 1
|
|
||||||
order by stu_sex asc,
|
|
||||||
年龄 desc;
|
|
||||||
|
|
||||||
-- 查询年龄最大的学生的出生日期
|
|
||||||
select min(stu_birth)
|
|
||||||
from tb_student;
|
|
||||||
|
|
||||||
-- 查询年龄最小的学生的出生日期
|
|
||||||
select max(stu_birth)
|
|
||||||
from tb_student;
|
|
||||||
|
|
||||||
-- 查询学号为1001的学生一共选了几门课
|
|
||||||
select count(*)
|
|
||||||
from tb_record
|
|
||||||
where stu_id = 1001;
|
|
||||||
|
|
||||||
-- 查询学号为1001的学生考试成绩的平均分
|
|
||||||
select round(avg(score), 1) as 平均分
|
|
||||||
from tb_record
|
|
||||||
where stu_id = 1001;
|
|
||||||
|
|
||||||
-- 查询学号为1001的学生考试成绩的平均分,如果有null值,null值算0分
|
|
||||||
-- 方法一:
|
|
||||||
select sum(score) / count(*)
|
|
||||||
from tb_record
|
|
||||||
where stu_id = 1001;
|
|
||||||
|
|
||||||
-- 方法二:
|
update tb_student
|
||||||
select avg(coalesce(score, 0))
|
set stu_name = '岳不嫣'
|
||||||
from tb_record
|
where stu_id = 1572;
|
||||||
where stu_id = 1001;
|
|
||||||
|
|
||||||
-- 查询学号为1001的学生考试成绩的标准差(聚合函数)
|
select stu_name
|
||||||
select stddev_samp(score)
|
from tb_student
|
||||||
from tb_record
|
where stu_name like '%不%'
|
||||||
where stu_id = 1001;
|
union all
|
||||||
|
select stu_name
|
||||||
|
from tb_student
|
||||||
|
where stu_name like '%嫣%';
|
||||||
|
|
||||||
-- 查询男女学生的人数
|
-- 16. 查询姓“杨”或姓“林”名字三个字的学生的姓名(正则表达式模糊查询)
|
||||||
select case stu_sex when 1 then '男' else '女' end as 性别,
|
-- regular expression
|
||||||
count(*) as 人数
|
select stu_name
|
||||||
from tb_student
|
from tb_student
|
||||||
group by stu_sex;
|
where stu_name regexp '[杨林][\\u4e00-\\u9fa5]{2}';
|
||||||
|
|
||||||
-- 查询每个学院学生人数
|
-- 17. 查询没有录入籍贯的学生姓名(空值处理)
|
||||||
select col_id as 学院编号,
|
select stu_name
|
||||||
count(*) as 人数
|
from tb_student
|
||||||
from tb_student
|
where stu_addr is null or trim(stu_addr) = '';
|
||||||
group by col_id;
|
|
||||||
|
|
||||||
-- 查询每个学院男女学生人数
|
|
||||||
select col_id as 学院编号,
|
|
||||||
case stu_sex when 1 then '男' else '女' end as 性别,
|
|
||||||
count(*) as 人数
|
|
||||||
from tb_student
|
|
||||||
group by col_id, stu_sex;
|
|
||||||
|
|
||||||
-- 查询每个学生的学号和平均成绩
|
|
||||||
select stu_id as 学号,
|
|
||||||
round(avg(score), 2) as 平均成绩
|
|
||||||
from tb_record
|
|
||||||
group by stu_id;
|
|
||||||
|
|
||||||
-- 查询平均成绩大于等于90分的学生的学号和平均成绩
|
|
||||||
-- 方法一:
|
|
||||||
select stu_id as 学号,
|
|
||||||
round(avg(score), 2) as 平均成绩
|
|
||||||
from tb_record
|
|
||||||
group by stu_id
|
|
||||||
having 平均成绩 >= 90;
|
|
||||||
|
|
||||||
-- 方法二:
|
|
||||||
select *
|
|
||||||
from ( select stu_id as 学号,
|
|
||||||
round(avg(score), 2) as 平均成绩
|
|
||||||
from tb_record
|
|
||||||
group by stu_id) as t
|
|
||||||
where 平均成绩 >= 90;
|
|
||||||
|
|
||||||
-- 查询1111、2222、3333三门课程平均成绩大于等于90分的学生的学号和平均成绩
|
|
||||||
select stu_id as 学号,
|
|
||||||
round(avg(score), 2) as 平均成绩
|
|
||||||
from tb_record
|
|
||||||
where cou_id in (1111, 2222, 3333)
|
|
||||||
group by stu_id
|
|
||||||
having avg(score) >= 90;
|
|
||||||
|
|
||||||
-- 嵌套查询:把一个查询的结果作为另外一个查询的一部分来使用
|
|
||||||
select stu_name
|
|
||||||
from tb_student
|
|
||||||
where stu_birth = (select min(stu_birth)
|
|
||||||
from tb_student);
|
|
||||||
|
|
||||||
-- 查询选了两门以上的课程的学生姓名
|
|
||||||
select stu_name
|
|
||||||
from tb_student
|
|
||||||
where stu_id in ( select stu_id
|
|
||||||
from tb_record
|
|
||||||
group by stu_id
|
|
||||||
having count(*) > 2);
|
|
||||||
|
|
||||||
-- 查询学生的姓名、生日和所在学院名称
|
|
||||||
-- 方法一:
|
|
||||||
select stu_name,
|
|
||||||
stu_birth,
|
|
||||||
col_name
|
|
||||||
from tb_student, tb_college
|
|
||||||
where tb_student.col_id = tb_college.col_id;
|
|
||||||
|
|
||||||
-- 方法二:
|
|
||||||
select stu_name,
|
|
||||||
stu_birth,
|
|
||||||
col_name
|
|
||||||
from tb_student inner join tb_college
|
|
||||||
on tb_student.col_id = tb_college.col_id;
|
|
||||||
|
|
||||||
-- 方法三:
|
|
||||||
select stu_name,
|
|
||||||
stu_birth,
|
|
||||||
col_name
|
|
||||||
from tb_student natural join tb_college;
|
|
||||||
|
|
||||||
-- 查询学生姓名、课程名称以及成绩
|
|
||||||
-- 方法一:
|
|
||||||
select stu_name,
|
|
||||||
cou_name,
|
|
||||||
score
|
|
||||||
from tb_student, tb_course, tb_record
|
|
||||||
where tb_student.stu_id = tb_record.stu_id
|
|
||||||
and tb_course.cou_id = tb_record.cou_id
|
|
||||||
and score is not null;
|
|
||||||
|
|
||||||
-- 方法二:
|
|
||||||
select stu_name,
|
|
||||||
cou_name,
|
|
||||||
score
|
|
||||||
from tb_student inner join tb_record inner join tb_course
|
|
||||||
on tb_student.stu_id = tb_record.stu_id
|
|
||||||
and tb_course.cou_id = tb_record.cou_id
|
|
||||||
where score is not null;
|
|
||||||
|
|
||||||
-- 方法三:
|
update tb_student
|
||||||
select stu_name,
|
set stu_addr = ' '
|
||||||
cou_name,
|
where stu_id = 1572;
|
||||||
score
|
|
||||||
from tb_student natural join tb_record natural join tb_course
|
|
||||||
where score is not null;
|
|
||||||
|
|
||||||
-- 补充:上面的查询结果取前5条数据
|
-- 18. 查询录入了籍贯的学生姓名(空值处理)
|
||||||
select stu_name,
|
select stu_name
|
||||||
cou_name,
|
from tb_student
|
||||||
score
|
where stu_addr is not null and trim(stu_addr) <> '';
|
||||||
from tb_student natural join tb_record natural join tb_course
|
|
||||||
where score is not null
|
|
||||||
order by stu_id asc, score desc
|
|
||||||
limit 5;
|
|
||||||
|
|
||||||
-- 补充:上面的查询结果取第6-10条数据
|
-- 19. 查询学生选课的所有日期(去重)
|
||||||
select stu_name,
|
select distinct sel_date
|
||||||
cou_name,
|
from tb_record;
|
||||||
score
|
|
||||||
from tb_student inner join tb_record inner join tb_course
|
|
||||||
on tb_student.stu_id = tb_record.stu_id
|
|
||||||
and tb_course.cou_id = tb_record.cou_id
|
|
||||||
order by stu_id asc, score desc
|
|
||||||
limit 5
|
|
||||||
offset 5;
|
|
||||||
|
|
||||||
-- 补充:上面的查询结果取第11-15条数据
|
-- 20. 查询学生的籍贯(空值处理和去重)
|
||||||
select stu_name,
|
select distinct stu_addr
|
||||||
cou_name,
|
from tb_student
|
||||||
score
|
where stu_addr is not null and trim(stu_addr) <> '';
|
||||||
from tb_student natural join tb_record natural join tb_course
|
|
||||||
where score is not null
|
|
||||||
order by stu_id asc, score desc
|
|
||||||
limit 5
|
|
||||||
offset 10;
|
|
||||||
|
|
||||||
-- 查询选课学生的姓名和平均成绩
|
-- 21. 查询男学生的姓名和生日按年龄从大到小排列(排序)
|
||||||
select stu_name,
|
-- ascending / descending
|
||||||
avg_score
|
select stu_name
|
||||||
from tb_student t1 inner join ( select stu_id,
|
, stu_birth
|
||||||
round(avg(score), 2) as avg_score
|
from tb_student
|
||||||
from tb_record
|
where stu_sex = 1
|
||||||
group by stu_id) t2
|
order by stu_birth asc;
|
||||||
on t1.stu_id = t2.stu_id;
|
|
||||||
|
|
||||||
-- 查询学生的姓名和选课的数量
|
-- 22. 将上面查询中的生日换算成年龄(日期函数、数值函数)
|
||||||
select stu_name,
|
-- 获取当前日期:curdate()
|
||||||
total
|
-- 计算时间差:timestampdiff(unit, date1, date2)
|
||||||
from tb_student t1 natural join ( select stu_id,
|
select stu_name
|
||||||
count(*) as total
|
, timestampdiff(year, stu_birth, curdate()) as stu_age
|
||||||
from tb_record
|
from tb_student
|
||||||
group by stu_id) t2;
|
where stu_sex = 1
|
||||||
|
order by stu_age desc;
|
||||||
|
|
||||||
-- 查询每个学生的姓名和选课数量(左外连接和子查询)
|
-- 聚合函数:max / min / avg / sum / count / std / variance
|
||||||
select stu_name as 姓名,
|
-- 聚合函数会自动忽略掉null
|
||||||
coalesce (total, 0) as 选课数量
|
-- 23. 查询年龄最大的学生的出生日期(聚合函数)
|
||||||
from tb_student t1 left join ( select stu_id,
|
select min(stu_birth)
|
||||||
count(*) as total
|
from tb_student;
|
||||||
from tb_record
|
|
||||||
group by stu_id) t2
|
-- 24. 查询年龄最小的学生的出生日期(聚合函数)
|
||||||
on t1.stu_id = t2.stu_id;
|
select max(stu_birth)
|
||||||
|
from tb_student;
|
||||||
|
|
||||||
|
-- 25. 查询编号为1111的课程考试成绩的最高分(聚合函数)
|
||||||
|
select max(score)
|
||||||
|
from tb_record
|
||||||
|
where cou_id = 1111;
|
||||||
|
|
||||||
|
-- 26. 查询学号为1001的学生考试成绩的最低分(聚合函数)
|
||||||
|
select min(score)
|
||||||
|
from tb_record
|
||||||
|
where stu_id = 1001;
|
||||||
|
|
||||||
|
-- 27. 查询学号为1001的学生考试成绩的平均分和标准差(聚合函数)
|
||||||
|
-- 四舍五入函数:round(num, n)
|
||||||
|
select round(avg(score), 1) as avg_score
|
||||||
|
, round(std(score), 4) as std_score
|
||||||
|
from tb_record
|
||||||
|
where stu_id = 1001;
|
||||||
|
|
||||||
|
-- 28. 查询学号为1001的学生考试成绩的平均分,如果有null值,null值算0分(聚合函数)
|
||||||
|
select sum(score) / count(*)
|
||||||
|
from tb_record
|
||||||
|
where stu_id = 1001;
|
||||||
|
|
||||||
|
-- 29. 查询男女学生的人数(分组和聚合函数)
|
||||||
|
select case stu_sex when 1 then '男' else '女' end as stu_sex
|
||||||
|
, count(*) as total
|
||||||
|
from tb_student
|
||||||
|
group by stu_sex;
|
||||||
|
|
||||||
|
-- 30. 查询每个学院学生人数(分组和聚合函数)
|
||||||
|
select col_id
|
||||||
|
, count(*) as total
|
||||||
|
from tb_student
|
||||||
|
group by col_id
|
||||||
|
with rollup;
|
||||||
|
|
||||||
|
-- 31. 查询每个学院男女学生人数(分组和聚合函数)
|
||||||
|
select col_id
|
||||||
|
, case stu_sex when 1 then '男' else '女' end as stu_sex
|
||||||
|
, count(*) as total
|
||||||
|
from tb_student
|
||||||
|
group by col_id, stu_sex;
|
||||||
|
|
||||||
|
-- 32. 查询选课学生的学号和平均成绩(分组和聚合函数)
|
||||||
|
select stu_id
|
||||||
|
, round(avg(score), 1) as avg_score
|
||||||
|
from tb_record
|
||||||
|
group by stu_id;
|
||||||
|
|
||||||
|
-- 33. 查询平均成绩大于等于90分的学生的学号和平均成绩(分组和聚合函数)
|
||||||
|
-- 结论:分组前的筛选使用where子句,分组后的筛选使用having子句
|
||||||
|
select stu_id
|
||||||
|
, round(avg(score), 1) as avg_score
|
||||||
|
from tb_record
|
||||||
|
group by stu_id
|
||||||
|
having avg(score) >= 90;
|
||||||
|
|
||||||
|
-- 34. 查询所有课程成绩大于80分的同学的学号(分组和聚合函数)
|
||||||
|
select stu_id
|
||||||
|
from tb_record
|
||||||
|
group by stu_id
|
||||||
|
having min(score) > 80;
|
||||||
|
|
||||||
|
-- Error Code: 1242. Subquery returns more than 1 row
|
||||||
|
select stu_id
|
||||||
|
, stu_name
|
||||||
|
from tb_student
|
||||||
|
where stu_id in (select stu_id
|
||||||
|
from tb_record
|
||||||
|
group by stu_id
|
||||||
|
having min(score) > 80);
|
||||||
|
|
||||||
|
-- 35. 查询年龄最大的学生的姓名(嵌套查询)
|
||||||
|
-- 嵌套查询/子查询:把一个查询的结果作为另外一个查询的一部分来使用
|
||||||
|
select @a := min(stu_birth)
|
||||||
|
from tb_student;
|
||||||
|
|
||||||
|
select stu_name
|
||||||
|
from tb_student
|
||||||
|
where stu_birth = @a;
|
||||||
|
|
||||||
|
select stu_name
|
||||||
|
from tb_student
|
||||||
|
where stu_birth = (select min(stu_birth)
|
||||||
|
from tb_student);
|
||||||
|
|
||||||
|
-- 36. 查询选了两门以上的课程的学生姓名(嵌套查询/分组/数据筛选)
|
||||||
|
select stu_name
|
||||||
|
from tb_student
|
||||||
|
where stu_id in (select stu_id
|
||||||
|
from tb_record
|
||||||
|
group by stu_id
|
||||||
|
having count(*) > 2);
|
||||||
|
|
||||||
|
-- 37. 查询学生的姓名、生日和所在学院名称(连接查询)
|
||||||
|
select stu_name
|
||||||
|
, stu_birth
|
||||||
|
, col_name
|
||||||
|
from tb_student, tb_college
|
||||||
|
where tb_student.col_id = tb_college.col_id;
|
||||||
|
|
||||||
|
select stu_name
|
||||||
|
, stu_birth
|
||||||
|
, col_name
|
||||||
|
from tb_student inner join tb_college
|
||||||
|
on tb_student.col_id = tb_college.col_id;
|
||||||
|
|
||||||
|
select stu_name
|
||||||
|
, stu_birth
|
||||||
|
, col_name
|
||||||
|
from tb_student natural join tb_college;
|
||||||
|
|
||||||
|
-- 38. 查询学生姓名、课程名称以及成绩(连接查询)
|
||||||
|
select stu_name
|
||||||
|
, cou_name
|
||||||
|
, score
|
||||||
|
from tb_student, tb_course, tb_record
|
||||||
|
where tb_student.stu_id = tb_record.stu_id
|
||||||
|
and tb_course.cou_id = tb_record.cou_id
|
||||||
|
and score is not null;
|
||||||
|
|
||||||
|
select stu_name
|
||||||
|
, cou_name
|
||||||
|
, score
|
||||||
|
from tb_student
|
||||||
|
inner join tb_record
|
||||||
|
on tb_student.stu_id = tb_record.stu_id
|
||||||
|
inner join tb_course
|
||||||
|
on tb_course.cou_id = tb_record.cou_id
|
||||||
|
where score is not null;
|
||||||
|
|
||||||
|
select stu_name
|
||||||
|
, cou_name
|
||||||
|
, score
|
||||||
|
from tb_student
|
||||||
|
natural join tb_record
|
||||||
|
natural join tb_course
|
||||||
|
where score is not null;
|
||||||
|
|
||||||
|
-- 39. 上面的查询结果按课程和成绩排序取前5条数据(分页查询)
|
||||||
|
select stu_name
|
||||||
|
, cou_name
|
||||||
|
, score
|
||||||
|
from tb_student
|
||||||
|
natural join tb_record
|
||||||
|
natural join tb_course
|
||||||
|
where score is not null
|
||||||
|
order by cou_id asc, score desc
|
||||||
|
limit 5;
|
||||||
|
|
||||||
|
-- 40. 上面的查询结果按课程和成绩排序取第6-10条数据(分页查询)
|
||||||
|
select stu_name
|
||||||
|
, cou_name
|
||||||
|
, score
|
||||||
|
from tb_student
|
||||||
|
natural join tb_record
|
||||||
|
natural join tb_course
|
||||||
|
where score is not null
|
||||||
|
order by cou_id asc, score desc
|
||||||
|
limit 5
|
||||||
|
offset 5;
|
||||||
|
|
||||||
|
-- 41. 上面的查询结果按课程和成绩排序取第11-15条数据(分页查询)
|
||||||
|
select stu_name
|
||||||
|
, cou_name
|
||||||
|
, score
|
||||||
|
from tb_student
|
||||||
|
natural join tb_record
|
||||||
|
natural join tb_course
|
||||||
|
where score is not null
|
||||||
|
order by cou_id asc, score desc
|
||||||
|
limit 5
|
||||||
|
offset 10;
|
||||||
|
|
||||||
|
-- 42. 查询选课学生的姓名和平均成绩(嵌套查询和连接查询)
|
||||||
|
select stu_name
|
||||||
|
, avg_score
|
||||||
|
from tb_student
|
||||||
|
natural join (select stu_id
|
||||||
|
, avg(score) as avg_score
|
||||||
|
from tb_record
|
||||||
|
group by stu_id) as tmp;
|
||||||
|
|
||||||
|
-- 43. 查询学生的姓名和选课的数量(嵌套查询和连接查询)
|
||||||
|
select stu_name
|
||||||
|
, total
|
||||||
|
from tb_student
|
||||||
|
inner join (select stu_id
|
||||||
|
, count(*) as total
|
||||||
|
from tb_record
|
||||||
|
group by stu_id) as tmp
|
||||||
|
on tb_student.stu_id = tmp.stu_id;
|
||||||
|
|
||||||
|
-- 44. 查询所有学生的姓名和选课数量(左外连接和嵌套查询)
|
||||||
|
-- 左外连接:把左表(写在join左边的表)所有的数据都拿到,不满足连表条件的地方填充null - left outer join
|
||||||
|
-- 右外连接:把右表(写在join右边的表)所有的数据都拿到,不满足连表条件的地方填充null - right outer join
|
||||||
|
-- 全外连接:把左表和右表的数据全部拿到即便它们不满足连表条件,MySQL不支持全外连接 - full outer join
|
||||||
|
select stu_name
|
||||||
|
, coalesce(total, 0) as total
|
||||||
|
from tb_student
|
||||||
|
left join (select stu_id
|
||||||
|
, count(*) as total
|
||||||
|
from tb_record
|
||||||
|
group by stu_id) as tmp
|
||||||
|
on tb_student.stu_id = tmp.stu_id;
|
||||||
|
|
||||||
|
-- 45. 查询没有选课的学生的姓名(左外连接和数据筛选)
|
||||||
|
select stu_name
|
||||||
|
from tb_student
|
||||||
|
left join tb_record
|
||||||
|
on tb_student.stu_id = tb_record.stu_id
|
||||||
|
where tb_record.stu_id is null;
|
||||||
```
|
```
|
||||||
|
|
||||||
上面的 DQL 有几个地方需要加以说明:
|
上面的 DQL 有几个地方需要加以说明:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## SQL详解之DCL
|
## 第44课:SQL详解之DCL
|
||||||
|
|
||||||
数据库服务器通常包含了非常重要的数据,可以通过访问控制来确保这些数据的安全,而 DCL 就是解决这一问题的,它可以为指定的用户授予访问权限或者从指定用户处召回指定的权限。DCL 对数据库管理员来说非常重要,因为用户权限的管理关系到数据库的安全。简单的说,我们可以通过 DCL 允许受信任的用户访问数据库,阻止不受信任的用户访问数据库,同时还可以通过 DCL 将每个访问者的的权限最小化(让访问者的权限刚刚够用)。
|
数据库服务器通常包含了非常重要的数据,可以通过访问控制来确保这些数据的安全,而 DCL 就是解决这一问题的,它可以为指定的用户授予访问权限或者从指定用户处召回指定的权限。DCL 对数据库管理员来说非常重要,因为用户权限的管理关系到数据库的安全。简单的说,我们可以通过 DCL 允许受信任的用户访问数据库,阻止不受信任的用户访问数据库,同时还可以通过 DCL 将每个访问者的的权限最小化(让访问者的权限刚刚够用)。
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## 索引
|
## 第45课:索引
|
||||||
|
|
||||||
索引是关系型数据库中用来提升查询性能最为重要的手段。关系型数据库中的索引就像一本书的目录,我们可以想象一下,如果要从一本书中找出某个知识点,但是这本书没有目录,这将是意见多么可怕的事情!我们估计得一篇一篇的翻下去,才能确定这个知识点到底在什么位置。创建索引虽然会带来存储空间上的开销,就像一本书的目录会占用一部分篇幅一样,但是在牺牲空间后换来的查询时间的减少也是非常显著的。
|
索引是关系型数据库中用来提升查询性能最为重要的手段。关系型数据库中的索引就像一本书的目录,我们可以想象一下,如果要从一本书中找出某个知识点,但是这本书没有目录,这将是意见多么可怕的事情!我们估计得一篇一篇的翻下去,才能确定这个知识点到底在什么位置。创建索引虽然会带来存储空间上的开销,就像一本书的目录会占用一部分篇幅一样,但是在牺牲空间后换来的查询时间的减少也是非常显著的。
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## 视图、函数和过程
|
## 第46课:视图、函数和过程
|
||||||
|
|
||||||
为了讲解视图、函数和过程,我们首先用下面的 DDL 和 DML 创建名为 hrs 的数据库并为其二维表添加如下所示的数据。
|
为了讲解视图、函数和过程,我们首先用下面的 DDL 和 DML 创建名为 hrs 的数据库并为其二维表添加如下所示的数据。
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## MySQL 新特性
|
## 第47课:MySQL 新特性
|
||||||
|
|
||||||
#### JSON类型
|
#### JSON类型
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## Python程序接入MySQL数据库
|
## 第48课:Python程序接入MySQL数据库
|
||||||
|
|
||||||
在 Python3 中,我们可以使用`mysqlclient`或者`pymysql`三方库来接入 MySQL 数据库并实现数据持久化操作。二者的用法完全相同,只是导入的模块名不一样。我们推荐大家使用纯 Python 的三方库`pymysql`,因为它更容易安装成功。下面我们仍然以之前创建的名为`hrs`的数据库为例,为大家演示如何通过 Python 程序操作 MySQL 数据库实现数据持久化操作。
|
在 Python3 中,我们可以使用`mysqlclient`或者`pymysql`三方库来接入 MySQL 数据库并实现数据持久化操作。二者的用法完全相同,只是导入的模块名不一样。我们推荐大家使用纯 Python 的三方库`pymysql`,因为它更容易安装成功。下面我们仍然以之前创建的名为`hrs`的数据库为例,为大家演示如何通过 Python 程序操作 MySQL 数据库实现数据持久化操作。
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue