From 965af7c53f4f34d3e392f8d02218089ef2a482e9 Mon Sep 17 00:00:00 2001 From: jackfrued Date: Mon, 6 Feb 2023 00:54:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=E6=96=87=E6=A1=A3=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=E5=92=8C=E7=AC=94=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 0 README.md | 0 第01课:初识Python.md | 0 第02课:第一个Python程序.md | 0 第03课:Python语言元素之变量.md | 0 第04课:Python语言元素之运算符.md | 0 第05课:分支结构.md | 0 第06课:循环结构.md | 0 第07课:分支和循环结构的应用.md | 0 第08课:常用数据结构之列表.md | 0 第09课:常用数据结构之元组.md | 0 第10课:常用数据结构之字符串.md | 0 第11课:常用数据结构之集合.md | 0 第12课:常用数据结构之字典.md | 0 第13课:函数和模块.md | 0 第14课:函数的应用.md | 0 第15课:函数使用进阶.md | 0 第16课:函数的高级应用.md | 0 第17课:面向对象编程入门.md | 0 第18课:面向对象编程进阶.md | 0 第19课:面向对象编程应用.md | 2 +- 第20课:Python标准库初探.md | 0 第21课:文件读写和异常处理.md | 0 ...课:对象的序列化和反序列化.md | 0 第23课:用Python读写CSV文件.md | 0 第24课:用Python读写Excel文件-1.md | 0 第25课:用Python读写Excel文件-2.md | 0 ...用Python操作Word文件和PowerPoint.md | 0 第27课:用Python操作PDF文件.md | 0 第28课:用Python处理图像.md | 0 第29课:用Python发送邮件和短信.md | 0 第30课:正则表达式的应用.md | 0 第31课:网络数据采集概述.md | 0 第32课:用Python获取网络资源.md | 0 第33课:用Python解析HTML页面.md | 0 第34课:Python中的并发编程-1.md | 0 第35课:Python中的并发编程-2.md | 0 第36课:Python中的并发编程-3.md | 0 ...课:并发编程在爬虫中的应用.md | 0 第38课:抓取网页动态内容.md | 0 第39课:爬虫框架Scrapy简介.md | 0 ...0课:关系型数据库和MySQL概述.md | 0 第41课.SQL详解之DDL.md | 2 +- 第42课.SQL详解之DML.md | 2 +- 第43课.SQL详解之DQL.md | 719 ++++++++++-------- 第44课.SQL详解之DCL.md | 2 +- 第45课.索引.md | 2 +- 第46课.视图+函数+过程.md | 2 +- 第47课.MySQL新特性.md | 2 +- 第48课.Python程序接入MySQL数据库.md | 2 +- 50 files changed, 390 insertions(+), 345 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 README.md mode change 100644 => 100755 第01课:初识Python.md mode change 100644 => 100755 第02课:第一个Python程序.md mode change 100644 => 100755 第03课:Python语言元素之变量.md mode change 100644 => 100755 第04课:Python语言元素之运算符.md mode change 100644 => 100755 第05课:分支结构.md mode change 100644 => 100755 第06课:循环结构.md mode change 100644 => 100755 第07课:分支和循环结构的应用.md mode change 100644 => 100755 第08课:常用数据结构之列表.md mode change 100644 => 100755 第09课:常用数据结构之元组.md mode change 100644 => 100755 第10课:常用数据结构之字符串.md mode change 100644 => 100755 第11课:常用数据结构之集合.md mode change 100644 => 100755 第12课:常用数据结构之字典.md mode change 100644 => 100755 第13课:函数和模块.md mode change 100644 => 100755 第14课:函数的应用.md mode change 100644 => 100755 第15课:函数使用进阶.md mode change 100644 => 100755 第16课:函数的高级应用.md mode change 100644 => 100755 第17课:面向对象编程入门.md mode change 100644 => 100755 第18课:面向对象编程进阶.md mode change 100644 => 100755 第19课:面向对象编程应用.md mode change 100644 => 100755 第20课:Python标准库初探.md mode change 100644 => 100755 第21课:文件读写和异常处理.md mode change 100644 => 100755 第22课:对象的序列化和反序列化.md mode change 100644 => 100755 第23课:用Python读写CSV文件.md mode change 100644 => 100755 第24课:用Python读写Excel文件-1.md mode change 100644 => 100755 第25课:用Python读写Excel文件-2.md mode change 100644 => 100755 第26课:用Python操作Word文件和PowerPoint.md mode change 100644 => 100755 第27课:用Python操作PDF文件.md mode change 100644 => 100755 第28课:用Python处理图像.md mode change 100644 => 100755 第29课:用Python发送邮件和短信.md mode change 100644 => 100755 第30课:正则表达式的应用.md mode change 100644 => 100755 第31课:网络数据采集概述.md mode change 100644 => 100755 第32课:用Python获取网络资源.md mode change 100644 => 100755 第33课:用Python解析HTML页面.md mode change 100644 => 100755 第34课:Python中的并发编程-1.md mode change 100644 => 100755 第35课:Python中的并发编程-2.md mode change 100644 => 100755 第36课:Python中的并发编程-3.md mode change 100644 => 100755 第37课:并发编程在爬虫中的应用.md mode change 100644 => 100755 第38课:抓取网页动态内容.md mode change 100644 => 100755 第39课:爬虫框架Scrapy简介.md mode change 100644 => 100755 第40课:关系型数据库和MySQL概述.md mode change 100644 => 100755 第41课.SQL详解之DDL.md mode change 100644 => 100755 第42课.SQL详解之DML.md mode change 100644 => 100755 第43课.SQL详解之DQL.md mode change 100644 => 100755 第44课.SQL详解之DCL.md mode change 100644 => 100755 第45课.索引.md mode change 100644 => 100755 第46课.视图+函数+过程.md mode change 100644 => 100755 第47课.MySQL新特性.md mode change 100644 => 100755 第48课.Python程序接入MySQL数据库.md diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/第01课:初识Python.md b/第01课:初识Python.md old mode 100644 new mode 100755 diff --git a/第02课:第一个Python程序.md b/第02课:第一个Python程序.md old mode 100644 new mode 100755 diff --git a/第03课:Python语言元素之变量.md b/第03课:Python语言元素之变量.md old mode 100644 new mode 100755 diff --git a/第04课:Python语言元素之运算符.md b/第04课:Python语言元素之运算符.md old mode 100644 new mode 100755 diff --git a/第05课:分支结构.md b/第05课:分支结构.md old mode 100644 new mode 100755 diff --git a/第06课:循环结构.md b/第06课:循环结构.md old mode 100644 new mode 100755 diff --git a/第07课:分支和循环结构的应用.md b/第07课:分支和循环结构的应用.md old mode 100644 new mode 100755 diff --git a/第08课:常用数据结构之列表.md b/第08课:常用数据结构之列表.md old mode 100644 new mode 100755 diff --git a/第09课:常用数据结构之元组.md b/第09课:常用数据结构之元组.md old mode 100644 new mode 100755 diff --git a/第10课:常用数据结构之字符串.md b/第10课:常用数据结构之字符串.md old mode 100644 new mode 100755 diff --git a/第11课:常用数据结构之集合.md b/第11课:常用数据结构之集合.md old mode 100644 new mode 100755 diff --git a/第12课:常用数据结构之字典.md b/第12课:常用数据结构之字典.md old mode 100644 new mode 100755 diff --git a/第13课:函数和模块.md b/第13课:函数和模块.md old mode 100644 new mode 100755 diff --git a/第14课:函数的应用.md b/第14课:函数的应用.md old mode 100644 new mode 100755 diff --git a/第15课:函数使用进阶.md b/第15课:函数使用进阶.md old mode 100644 new mode 100755 diff --git a/第16课:函数的高级应用.md b/第16课:函数的高级应用.md old mode 100644 new mode 100755 diff --git a/第17课:面向对象编程入门.md b/第17课:面向对象编程入门.md old mode 100644 new mode 100755 diff --git a/第18课:面向对象编程进阶.md b/第18课:面向对象编程进阶.md old mode 100644 new mode 100755 diff --git a/第19课:面向对象编程应用.md b/第19课:面向对象编程应用.md old mode 100644 new mode 100755 index e99062b..863a027 --- a/第19课:面向对象编程应用.md +++ b/第19课:面向对象编程应用.md @@ -1,4 +1,4 @@ -## 第18课:面向对象编程应用 +## 第19课:面向对象编程应用 面向对象编程对初学者来说不难理解但很难应用,虽然我们为大家总结过面向对象的三步走方法(定义类、创建对象、给对象发消息),但是说起来容易做起来难。**大量的编程练习**和**阅读优质的代码**可能是这个阶段最能够帮助到大家的两件事情。接下来我们还是通过经典的案例来剖析面向对象编程的知识,同时也通过这些案例为大家讲解如何运用之前学过的Python知识。 diff --git a/第20课:Python标准库初探.md b/第20课:Python标准库初探.md old mode 100644 new mode 100755 diff --git a/第21课:文件读写和异常处理.md b/第21课:文件读写和异常处理.md old mode 100644 new mode 100755 diff --git a/第22课:对象的序列化和反序列化.md b/第22课:对象的序列化和反序列化.md old mode 100644 new mode 100755 diff --git a/第23课:用Python读写CSV文件.md b/第23课:用Python读写CSV文件.md old mode 100644 new mode 100755 diff --git a/第24课:用Python读写Excel文件-1.md b/第24课:用Python读写Excel文件-1.md old mode 100644 new mode 100755 diff --git a/第25课:用Python读写Excel文件-2.md b/第25课:用Python读写Excel文件-2.md old mode 100644 new mode 100755 diff --git a/第26课:用Python操作Word文件和PowerPoint.md b/第26课:用Python操作Word文件和PowerPoint.md old mode 100644 new mode 100755 diff --git a/第27课:用Python操作PDF文件.md b/第27课:用Python操作PDF文件.md old mode 100644 new mode 100755 diff --git a/第28课:用Python处理图像.md b/第28课:用Python处理图像.md old mode 100644 new mode 100755 diff --git a/第29课:用Python发送邮件和短信.md b/第29课:用Python发送邮件和短信.md old mode 100644 new mode 100755 diff --git a/第30课:正则表达式的应用.md b/第30课:正则表达式的应用.md old mode 100644 new mode 100755 diff --git a/第31课:网络数据采集概述.md b/第31课:网络数据采集概述.md old mode 100644 new mode 100755 diff --git a/第32课:用Python获取网络资源.md b/第32课:用Python获取网络资源.md old mode 100644 new mode 100755 diff --git a/第33课:用Python解析HTML页面.md b/第33课:用Python解析HTML页面.md old mode 100644 new mode 100755 diff --git a/第34课:Python中的并发编程-1.md b/第34课:Python中的并发编程-1.md old mode 100644 new mode 100755 diff --git a/第35课:Python中的并发编程-2.md b/第35课:Python中的并发编程-2.md old mode 100644 new mode 100755 diff --git a/第36课:Python中的并发编程-3.md b/第36课:Python中的并发编程-3.md old mode 100644 new mode 100755 diff --git a/第37课:并发编程在爬虫中的应用.md b/第37课:并发编程在爬虫中的应用.md old mode 100644 new mode 100755 diff --git a/第38课:抓取网页动态内容.md b/第38课:抓取网页动态内容.md old mode 100644 new mode 100755 diff --git a/第39课:爬虫框架Scrapy简介.md b/第39课:爬虫框架Scrapy简介.md old mode 100644 new mode 100755 diff --git a/第40课:关系型数据库和MySQL概述.md b/第40课:关系型数据库和MySQL概述.md old mode 100644 new mode 100755 diff --git a/第41课.SQL详解之DDL.md b/第41课.SQL详解之DDL.md old mode 100644 new mode 100755 index 9bd11f7..55c5b51 --- a/第41课.SQL详解之DDL.md +++ b/第41课.SQL详解之DDL.md @@ -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`。 diff --git a/第42课.SQL详解之DML.md b/第42课.SQL详解之DML.md old mode 100644 new mode 100755 index 78f28db..a7e83ed --- a/第42课.SQL详解之DML.md +++ b/第42课.SQL详解之DML.md @@ -1,4 +1,4 @@ -## SQL详解之DML +## 第42课:SQL详解之DML 我们接着上一课中创建的学校选课系统数据库,为大家讲解 DML 的使用。DML 可以帮助将数据插入到二维表(`insert`操作)、从二维表删除数据(`delete`操作)以及更新二维表的数据(`update`操作)。在执行 DML 之前,我们先通过下面的`use`命令切换到`school`数据库。 diff --git a/第43课.SQL详解之DQL.md b/第43课.SQL详解之DQL.md old mode 100644 new mode 100755 index 480d1c7..418f050 --- a/第43课.SQL详解之DQL.md +++ b/第43课.SQL详解之DQL.md @@ -1,370 +1,415 @@ -## SQL详解之DQL +## 第43课:SQL详解之DQL 接下来,我们利用之前创建的学校选课系统数据库,为大家讲解 DQL 的应用。无论对于开发人员还是数据分析师,DQL 都是非常重要的,它关系着我们能否从关系数据库中获取我们需要的数据。建议大家把上上一节课中建库建表的 DDL 以及 上一节课中插入数据的 DML 重新执行一次,确保表和数据跟没有问题再执行下面的操作。 ```SQL use `school`; --- 查询所有学生的所有信息 --- 说明:实际工作中不建议使用 select * 的方式进行查询 -select * - from tb_student; - --- 查询学生的学号、姓名和籍贯 -select stu_id, - stu_name, - stu_addr - from tb_student; +-- 01. 查询所有学生的所有信息 +select * + from tb_student; -select stu_id as 学号, - stu_name as 姓名, - stu_addr as 籍贯 - from tb_student; +select stu_id + , stu_name + , stu_sex + , stu_birth + , stu_addr + , col_id + from tb_student; --- 查询所有课程的名称及学分 -select cou_name as 课程名称, - cou_credit as 学分 - from tb_course; +-- 02. 查询学生的学号、姓名和籍贯(投影和别名) +select stu_id as 学号 + , stu_name as 姓名 + , stu_addr as 籍贯 + from tb_student; --- 查询所有女学生的姓名和出生日期 -select stu_name, - stu_birth - from tb_student - where stu_sex=0; +-- 03. 查询所有课程的名称及学分(投影和别名) +select cou_name as 课程名称 + , cou_credit as 学分 + from tb_course; --- 查询籍贯为“四川成都”的女学生的姓名和出生日期 -select stu_name, - stu_birth - from tb_student - where stu_sex=0 - and stu_addr='四川成都'; +-- 04. 查询所有女学生的姓名和出生日期(数据筛选) +select stu_name + , stu_birth + from tb_student + where stu_sex = 0; --- 查询籍贯为“四川成都”或者性别是女的学生 -select stu_name, - stu_birth - from tb_student - where stu_sex=0 - or stu_addr='四川成都'; +-- 05. 查询籍贯为“四川成都”的女学生的姓名和出生日期(数据筛选) +select stu_name + , stu_birth + from tb_student + where stu_sex = 0 and stu_addr = '四川成都'; --- 查询所有80后学生的姓名、性别和出生日期 --- 方法一: -select stu_name, - stu_sex, - stu_birth - from tb_student - where stu_birth >= '1980-1-1' - and stu_birth <= '1989-12-31'; +-- 06. 查询籍贯为“四川成都”或者性别是女的学生(数据筛选) +select stu_name + , stu_birth + from tb_student + where stu_sex = 0 or stu_addr = '四川成都'; --- 方法二: -select stu_name, - stu_sex, - stu_birth - from tb_student - where stu_birth between '1980-1-1' and '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; +-- 07. 查询所有80后学生的姓名、性别和出生日期(数据筛选) +select stu_name + , stu_sex + , stu_birth + from tb_student + where '1980-1-1' <= stu_birth and stu_birth <= '1989-12-31'; --- 查询姓“杨”的学生姓名和性别(模糊) --- % 可以匹配零个或任意多个字符 -select stu_name, - stu_sex - from tb_student - where stu_name like '杨%'; +select stu_name + , stu_sex + , stu_birth + from tb_student + where stu_birth between '1980-1-1' and '1989-12-31'; --- 查询姓“杨”名字两个字的学生姓名和性别(模糊) --- _ 可以匹配一个字符 -select stu_name, - stu_sex - from tb_student - where stu_name like '杨_'; +-- MySQL方言 +select stu_name + , if(stu_sex, '男', '女') as stu_sex + , stu_birth + from tb_student + where stu_birth between '1980-1-1' and '1989-12-31'; --- 查询姓“杨”名字三个字的学生姓名和性别(模糊) -select stu_name, - stu_sex - from tb_student - where stu_name like '杨__'; +select stu_name + , case stu_sex + when 1 then '男' + else '女' + end as stu_sex + , stu_birth + from tb_student + where stu_birth between '1980-1-1' and '1989-12-31'; --- 查询名字中有“不”字或“嫣”字的学生的姓名(模糊) --- 方法一: -select stu_name, - stu_sex - from tb_student - where stu_name like '%不%' - or stu_name like '%嫣%'; +-- 08. 查询学分大于2分的课程名称和学分(数据筛选) +select cou_name + , cou_credit + from tb_course + where cou_credit > 2; --- 方法二: -select stu_name, - stu_sex - from tb_student - where stu_name like '%不%' +-- 09. 查询学分是奇数的课程的名称和学分(数据筛选) +select cou_name + , cou_credit + from tb_course + 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 -select stu_name, - stu_sex - from tb_student - 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; +select stu_name + from tb_student + where stu_name like '%嫣%'; --- 方法二: -select avg(coalesce(score, 0)) - from tb_record - where stu_id = 1001; +update tb_student + set stu_name = '岳不嫣' + where stu_id = 1572; --- 查询学号为1001的学生考试成绩的标准差(聚合函数) -select stddev_samp(score) - from tb_record - where stu_id = 1001; +select stu_name + from tb_student + where stu_name like '%不%' + union all +select stu_name + from tb_student + where stu_name like '%嫣%'; --- 查询男女学生的人数 - select case stu_sex when 1 then '男' else '女' end as 性别, - count(*) as 人数 - from tb_student -group by stu_sex; +-- 16. 查询姓“杨”或姓“林”名字三个字的学生的姓名(正则表达式模糊查询) +-- regular expression +select stu_name + from tb_student + where stu_name regexp '[杨林][\\u4e00-\\u9fa5]{2}'; --- 查询每个学院学生人数 - select col_id as 学院编号, - count(*) as 人数 - from tb_student -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; +-- 17. 查询没有录入籍贯的学生姓名(空值处理) +select stu_name + from tb_student + where stu_addr is null or trim(stu_addr) = ''; --- 方法三: -select stu_name, - cou_name, - score - from tb_student natural join tb_record natural join tb_course - where score is not null; +update tb_student + set stu_addr = ' ' + where stu_id = 1572; --- 补充:上面的查询结果取前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 stu_id asc, score desc - limit 5; +-- 18. 查询录入了籍贯的学生姓名(空值处理) +select stu_name + from tb_student + where stu_addr is not null and trim(stu_addr) <> ''; --- 补充:上面的查询结果取第6-10条数据 - 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 -order by stu_id asc, score desc - limit 5 - offset 5; +-- 19. 查询学生选课的所有日期(去重) +select distinct sel_date + from tb_record; --- 补充:上面的查询结果取第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 stu_id asc, score desc - limit 5 - offset 10; +-- 20. 查询学生的籍贯(空值处理和去重) +select distinct stu_addr + from tb_student + where stu_addr is not null and trim(stu_addr) <> ''; --- 查询选课学生的姓名和平均成绩 -select stu_name, - avg_score - from tb_student t1 inner join ( select stu_id, - round(avg(score), 2) as avg_score - from tb_record - group by stu_id) t2 - on t1.stu_id = t2.stu_id; +-- 21. 查询男学生的姓名和生日按年龄从大到小排列(排序) +-- ascending / descending +select stu_name + , stu_birth + from tb_student + where stu_sex = 1 + order by stu_birth asc; --- 查询学生的姓名和选课的数量 -select stu_name, - total - from tb_student t1 natural join ( select stu_id, - count(*) as total - from tb_record - group by stu_id) t2; +-- 22. 将上面查询中的生日换算成年龄(日期函数、数值函数) +-- 获取当前日期:curdate() +-- 计算时间差:timestampdiff(unit, date1, date2) +select stu_name + , timestampdiff(year, stu_birth, curdate()) as stu_age + from tb_student + where stu_sex = 1 + order by stu_age desc; --- 查询每个学生的姓名和选课数量(左外连接和子查询) -select stu_name as 姓名, - coalesce (total, 0) as 选课数量 - from tb_student t1 left join ( select stu_id, - count(*) as total - from tb_record - group by stu_id) t2 - on t1.stu_id = t2.stu_id; +-- 聚合函数:max / min / avg / sum / count / std / variance +-- 聚合函数会自动忽略掉null +-- 23. 查询年龄最大的学生的出生日期(聚合函数) +select min(stu_birth) + from tb_student; + +-- 24. 查询年龄最小的学生的出生日期(聚合函数) +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 有几个地方需要加以说明: diff --git a/第44课.SQL详解之DCL.md b/第44课.SQL详解之DCL.md old mode 100644 new mode 100755 index e3bb186..9c797aa --- a/第44课.SQL详解之DCL.md +++ b/第44课.SQL详解之DCL.md @@ -1,4 +1,4 @@ -## SQL详解之DCL +## 第44课:SQL详解之DCL 数据库服务器通常包含了非常重要的数据,可以通过访问控制来确保这些数据的安全,而 DCL 就是解决这一问题的,它可以为指定的用户授予访问权限或者从指定用户处召回指定的权限。DCL 对数据库管理员来说非常重要,因为用户权限的管理关系到数据库的安全。简单的说,我们可以通过 DCL 允许受信任的用户访问数据库,阻止不受信任的用户访问数据库,同时还可以通过 DCL 将每个访问者的的权限最小化(让访问者的权限刚刚够用)。 diff --git a/第45课.索引.md b/第45课.索引.md old mode 100644 new mode 100755 index 7691a55..a38bb64 --- a/第45课.索引.md +++ b/第45课.索引.md @@ -1,4 +1,4 @@ -## 索引 +## 第45课:索引 索引是关系型数据库中用来提升查询性能最为重要的手段。关系型数据库中的索引就像一本书的目录,我们可以想象一下,如果要从一本书中找出某个知识点,但是这本书没有目录,这将是意见多么可怕的事情!我们估计得一篇一篇的翻下去,才能确定这个知识点到底在什么位置。创建索引虽然会带来存储空间上的开销,就像一本书的目录会占用一部分篇幅一样,但是在牺牲空间后换来的查询时间的减少也是非常显著的。 diff --git a/第46课.视图+函数+过程.md b/第46课.视图+函数+过程.md old mode 100644 new mode 100755 index 1c45b2d..6d32e09 --- a/第46课.视图+函数+过程.md +++ b/第46课.视图+函数+过程.md @@ -1,4 +1,4 @@ -## 视图、函数和过程 +## 第46课:视图、函数和过程 为了讲解视图、函数和过程,我们首先用下面的 DDL 和 DML 创建名为 hrs 的数据库并为其二维表添加如下所示的数据。 diff --git a/第47课.MySQL新特性.md b/第47课.MySQL新特性.md old mode 100644 new mode 100755 index 38c05c5..5b729a9 --- a/第47课.MySQL新特性.md +++ b/第47课.MySQL新特性.md @@ -1,4 +1,4 @@ -## MySQL 新特性 +## 第47课:MySQL 新特性 #### JSON类型 diff --git a/第48课.Python程序接入MySQL数据库.md b/第48课.Python程序接入MySQL数据库.md old mode 100644 new mode 100755 index 24f1fbc..504d8a8 --- a/第48课.Python程序接入MySQL数据库.md +++ b/第48课.Python程序接入MySQL数据库.md @@ -1,4 +1,4 @@ -## Python程序接入MySQL数据库 +## 第48课:Python程序接入MySQL数据库 在 Python3 中,我们可以使用`mysqlclient`或者`pymysql`三方库来接入 MySQL 数据库并实现数据持久化操作。二者的用法完全相同,只是导入的模块名不一样。我们推荐大家使用纯 Python 的三方库`pymysql`,因为它更容易安装成功。下面我们仍然以之前创建的名为`hrs`的数据库为例,为大家演示如何通过 Python 程序操作 MySQL 数据库实现数据持久化操作。