From 3a1370a24621479bd0b394a6bbcebf7fd4d643fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=B5=E5=BF=B5?= <2324752546@qq.com> Date: Sun, 5 Mar 2023 00:26:26 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E7=AC=AC=E5=85=AD=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20230304 \345\207\275\346\225\260.md" | 352 ++++++++++++++++++ 1 file changed, 352 insertions(+) create mode 100644 "47 \346\235\216\345\277\265\345\277\265/20230304 \345\207\275\346\225\260.md" diff --git "a/47 \346\235\216\345\277\265\345\277\265/20230304 \345\207\275\346\225\260.md" "b/47 \346\235\216\345\277\265\345\277\265/20230304 \345\207\275\346\225\260.md" new file mode 100644 index 0000000..c8afb3a --- /dev/null +++ "b/47 \346\235\216\345\277\265\345\277\265/20230304 \345\207\275\346\225\260.md" @@ -0,0 +1,352 @@ +# 笔记: + +#### 一、关联查询: + +关联查询: +当select语句基于两个或更多个表一起查询时,称为关联查询,或联合查询。 + +1、联合查询的结果有7种情况: +(1)A∩B +(2)A +(3)A - A∩B +(4)B +(5)B - A∩B +(6)A∪B +(7)A∪B - A∩B + +2、关联查询有几种情况,分别实现什么结果 +(1)内连接:INNER JOIN +实现结果:A∩B + +(2)左外连接,简称左连接:A LEFT JOIN B +实现结果:A 或 A - A∩B + +(3)右外连接,简称右连接:A RIGHT JOIN B +实现结果:B 或 B - A∩B + +(4)全外连接,简称全连接: A FULL JOIN B(但是mysql不支持这种写法) +Mysql通过合并左连接和右连接的结果实现全连接的效果。 + + +实现A结果的左连接 union 实现B结果的右连接 = A∪B + +实现A - A∩B结果的左连接 union 实现B - A∩B结果的右连接 = A∪B - A∩B + +#### 1.内连接: + +观察数据: +t_employee 看成A表 +t_department 看成B表 +此时t_employee (A表)中有 李红和周洲的did是NULL,没有对应部门, + t_department(B表)中有 测试部,在员工表中找不到对应记录的。 + +#查询所有员工的姓名,部门编号,部门名称 +#如果员工没有部门的,不要 +#如果部门没有员工的,不要 + +员工的姓名在t_employee (A表)中 +部门的编号,在t_employee (A表)和t_department(B表)都有 +部门名称在t_department(B表)中 +所以需要联合两个表一起查询。 + +(1)凡是联合查询的两个表,必须有“关联字段”, +关联字段是逻辑意义一样,数据类型一样,名字可以一样也可以不一样的两个字段。 +比如:t_employee (A表)中did和t_department(B表)中的did。 + +发现关联字段其实就是可以建外键的字段。当然联合查询不要求一定建外键。 + +(2)联合查询必须写关联条件,关联条件的个数 = n - 1. +n是联合查询的表的数量。 +如果2个表一起联合查询,关联条件数量是1, +如果3个表一起联合查询,关联条件数量是2, +如果4个表一起联合查询,关联条件数量是3, +。。。。 +否则就会出现笛卡尔积现象,这是应该避免的。 + +(3)关联条件可以用on子句编写,也可以写到where中。 +但是建议用on单独编写,这样呢,可读性更好。 + +每一个join后面都要加on子句 +A inner|left|right join B on 条件 +A inner|left|right join B on 条件 inner|left|right jon C on 条件 + +#### 2.左连接: + +t_employee 看成A表 +t_department 看成B表 +此时t_employee (A表)中有 李红和周洲的did是NULL,没有对应部门, + t_department(B表)中有 测试部,在员工表中找不到对应记录的。 + +#### 3.有链接 + +t_employee 看成A表 +t_department 看成B表 +此时t_employee (A表)中有 李红和周洲的did是NULL,没有对应部门, + t_department(B表)中有 测试部,在员工表中找不到对应记录的。 + +查询的结果是B - A∩B A right join B +此时的where条件,建议写子表的关联字段is null,这样更准确一点。 +如果要建外键,它们肯定有子表和父表的角色,写子表的关联字段is null +因为父表中这个字段一般是主键,不会为null。 + +#### 4.自连接: + +演示特殊的联合查询/关联查询/多表查询:自连接 +物理上,是一张表 +逻辑上,是两张表 +分析表结构:t_employee表 +mid:是表示存储员工的领导编号。即该员工归谁管。 + 领导编号其中就是“领导”作为员工的员工编号 + 例如:eid为3的员工邓超远,他的mid是7,表示他的领导是员工编号为7的员工。 + eid为7的员工是贾宝玉,他的eid是7,贾宝玉作为员工来说,他的编号是7, + 作为领导来说,他的编号也是7。 + +mid的取值范围受到eid字段的限制。mid的值选择必须是eid有的值范围。 + +可以理解为mid和eid是关联字段,如果要建外键,可以在mid字段上建外键。 +foreign key(mid) references t_employee(eid) + +此时t_employee既是子表也是父表。 +员工表t_employee建立了外键: +CONSTRAINT `t_employee_ibfk_3` FOREIGN KEY (`mid`) REFERENCES `t_employee` (`eid`) ON DELETE SET NULL ON UPDATE CASCADE + +#### 二、分组函数: + +1.统计 count + +2.最大值 max + +3.最小值 min + +4.求和 sum + +5.平均值 avg + +#### 三、 + + + +# 作业: + +~~~ mysql +create database class charset utf8; +use class; +CREATE TABLE `student` +( + `Sno` varchar(20) NOT NULL, + `Sname` varchar(20) NOT NULL, + `Ssex` varchar(20) NOT NULL, + `Sbirthday` datetime DEFAULT NULL, + `Class` varchar(20) DEFAULT NULL, + PRIMARY KEY (`Sno`) +); +CREATE TABLE `course` +( + `Cno` varchar(20) NOT NULL, + `Cname` varchar(20) NOT NULL, + `Tno` varchar(20) NOT NULL, + PRIMARY KEY (`Cno`), + KEY `tno` (`Tno`), + CONSTRAINT `tno` FOREIGN KEY (`Tno`) REFERENCES `teacher` (`Tno`) +); +CREATE TABLE `score` +( + `Sno` varchar(20) NOT NULL, + `Cno` varchar(20) NOT NULL, + `Degree` decimal(4, 1) DEFAULT NULL, + PRIMARY KEY (`Sno`, `Cno`), + KEY `cno` (`Cno`), + CONSTRAINT `cno` FOREIGN KEY (`Cno`) REFERENCES `course` (`Cno`), + CONSTRAINT `sno` FOREIGN KEY (`Sno`) REFERENCES `student` (`Sno`) +); +CREATE TABLE `teacher` +( + `Tno` varchar(20) NOT NULL, + `Tname` varchar(20) NOT NULL, + `Tsex` varchar(20) NOT NULL, + `Tbirthday` datetime DEFAULT NULL, + `Prof` varchar(20) DEFAULT NULL, + `Depart` varchar(20) NOT NULL, + PRIMARY KEY (`Tno`) +); +insert into student +values (108, '曾华', '男', '1977-9-1', 95033), + (105, '匡明', '男', '1975-10-2', 95031), + (107, '王丽', '女', '1976-1-23', 95033), + (101, '李军', '男', '1976-2-20', 95033), + (109, '王芳', '女', '1975-2-10', 95031), + (103, '陆君', '男', '1974-6-3', 95031); +insert into Course +values ('3-105', '计算机导论', 825), + ('3-245', '操作系统', 804), + ('6-166', '数字电路', 856), + ('9-888', '高等数学', 831); +insert into score +values ('103', '3-245', 86), + ('105', '3-245', 75), + ('109', '3-245', 68), + ('103', '3-105', 92), + ('105', '3-105', 88), + ('109', '3-105', 76), + ('101', '3-105', 64), + ('107', '3-105', 91), + ('108', '3-105', 78), + ('101', '6-166', 85), + ('107', '6-166', 79), + ('108', '6-166', 81); +insert into teacher +values (804, '李诚', '男', '1958-12-2', '副教授', '计算机系'), + (856, '张旭', '男', '1969-3-12', '讲师', '电子工程系'), + (825, '王萍', '女', '1972-5-5', '助教', '计算机系'), + (831, '刘冰', '女', '1977-8-14', '助教', '电子工程系'); +# 1,查询所有学生,都学了哪些课程,要显示学生信息和课程信息 +select * +from student + inner join score on student.Sno = score.Sno + inner join course on score.Cno = course.Cno; +# 2,查询没有学生的教师的所有信息 +select teacher.* +from teacher + left join course on teacher.Tno = course.Tno + left join score on course.Cno = score.Cno +where + Sno is null; +# ① 查询Score表中的最高分的学生学号和课程号。 +select s.Sno, Sname,cno +from student s + inner join score on s.Sno = score.Sno +where + Degree = (select max(Degree) from score); +# ② 查询所有学生的Sname、Cno和Degree列。 +select Sname, score.Cno, Degree +from student, + score +where student.Sno = score.Sno; +# ③ 查询所有学生的Sno、Cname和Degree列。 +select Sno, Cname, Degree +from course, + score +where course.Cno = score.Cno; +# ④ 查询所有学生的Sname、Cname和Degree列。 +select Sname, Cname, Degree +from student, + course, + score +where student.Sno = score.Sno + and course.Cno = score.Cno; +# ⑤ 查询“95033”班学生的平均分。 +select class,avg(Degree) from score s,student s2 where s.Sno = s2.Sno and class=95033; +# ⑥ 查询选修“3-105”课程的成绩高于“109”号同学成绩的所有同学的记录。 +select student.* +from student + inner join score on student.Sno = score.Sno +where Cno = '3-105' + and Degree > (student.Sno = 109); +# ⑦ 查询score中选学多门课程的同学中分数为非最高分成绩的记录。 +select max(Degree) +from score +group by Cno; +select * +from score +where Degree not in (select max(Degree) from score group by Cno); +# ⑧ 查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。 +select * +from score +where cno = '3-105' + and Degree > (sno = 109); +# ⑨ 查询和学号为108的同学同年出生的所有学生的Sno、Sname和Sbirthday列。 +select Sno, Sname, Sbirthday +from student +where Sbirthday = (sno = 108); +# ⑩ 查询“张旭“教师任课的学生成绩。 +select Sno, Degree +from score s + inner join course c on c.cno = s.cno + inner join teacher t on c.Tno = t.Tno +where tname = '张旭'; +# 11 查询选修某课程的同学人数多于5人的教师姓名。 +select tname, count(c.Tno) +from score s + inner join course c on s.Cno = c.Cno + inner join teacher t on c.Tno = t.Tno +group by tname +having count(c.tno) > 5; +# 12 查询出“计算机系“教师所教课程的成绩表。 +select Depart, tname, sno, s.Cno, Degree +from teacher t + inner join course c on t.Tno = c.Tno + inner join score s on c.Cno = s.Cno +where Depart = '计算机系'; +# 13 查询“计算机系”与“电子工程系“不同职称的教师的Tname和Prof。 +select Tname, Prof, Depart +from teacher +where Depart = '计算机系' + or Depart = '电子工程系'; +# 14 查询选修编号为“3-105“课程且成绩至少高于选修编号为“3-245”的同学的Cno、Sno和Degree,并按Degree从高到低次序排序。 +select cno, st.Sno, degree +from score s + inner join student st on s.Sno = st.Sno +where cno = '3-105' + and Degree > (cno = '3-245') +order by degree desc +; +# 15 查询选修编号为“3-105”且成绩高于选修编号为“3-245”课程的同学的Cno、Sno和Degree. +select s.Cno, Sno, Degree +from score s + inner join course c on s.Cno = c.Cno +where c.Cno = '3-105' + and Degree > (c.Cno = '3-245'); +# 16 查询成绩比该课程平均成绩低的同学的成绩表。 +select avg(Degree) +from score +group by Cno; +select * +from score +where Degree < (select avg(Degree) from score); +# 17 查询所有任课教师的Tname和Depart. +select Tname, depart +from teacher; +# 18 查询所有未讲课的教师的Tname和Depart. +select Tname, Depart +from teacher t + left join course c on t.Tno = c.Tno + left join score s on s.Cno = c.Cno +where Sno is null; +# 19 查询“男”教师及其所上的课程。 +select c.* +from course c + inner join teacher t on c.Tno = t.Tno +where Tsex = '男'; +# 20 查询最高分同学的Sno、Cno和Degree列。 +select Sno, Cno, max(Degree) +from score; +# 21 查询和“李军”同性别的所有同学的Sname. +select Ssex +from student +where Sname = '李军'; +select Sname +from student +where Ssex = (select Ssex from student where Sname = '李军'); +# 22 查询和“李军”同性别并同班的同学Sname. +select class +from student +where Sname = '李军'; +select Sname +from student +where Ssex = (select Ssex from student where Sname = '李军') +and + class not in (select class +from student +where Sname = '李军'); +# 23 查询所有选修“计算机导论”课程的“男”同学的成绩表。 +select s.* from score s +inner join student s2 on s.Sno = s2.Sno +inner join course c on s.Cno = c.Cno +where + Cname = '计算机导论' +and + Ssex='男'; +~~~ + + + -- Gitee From 70f3551a2d78b5701da0288e3580d9a619d4ca2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=B5=E5=BF=B5?= <2324752546@qq.com> Date: Tue, 7 Mar 2023 22:24:41 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E7=AC=AC=E4=B8=83=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...7 \345\255\220\346\237\245\350\257\242.md" | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 "47 \346\235\216\345\277\265\345\277\265/20230307 \345\255\220\346\237\245\350\257\242.md" diff --git "a/47 \346\235\216\345\277\265\345\277\265/20230307 \345\255\220\346\237\245\350\257\242.md" "b/47 \346\235\216\345\277\265\345\277\265/20230307 \345\255\220\346\237\245\350\257\242.md" new file mode 100644 index 0000000..583221c --- /dev/null +++ "b/47 \346\235\216\345\277\265\345\277\265/20230307 \345\255\220\346\237\245\350\257\242.md" @@ -0,0 +1,142 @@ +# 笔记: + + + +# 作业: + +```mysql +create database works charset utf8; +use works; +create table stuinfo +( + stuNo varchar(10) primary key, + stuName varchar(5) not null, + stuSex enum ('男','女') not null, + stuAge int not null, + stuAddress varchar(5) not null, + stuSeat int not null +); +CREATE TABLE stuexam +( + `examNO` int(11) NOT NULL, + `stuNO` varchar(5) NOT NULL, + `writtenExam` int(11) NOT NULL, + `labExam` int(11) NOT NULL, + PRIMARY KEY (`examNO`), + KEY `stuNO` (`stuNO`), + CONSTRAINT `stuNO` FOREIGN KEY (`stuNO`) REFERENCES `stuinfo` (`stuNo`) +); +CREATE TABLE stumarks +( + `examNO` int(11) NOT NULL, + `stuID` varchar(5) NOT NULL, + `score` int(11) NOT NULL, + KEY `examNO` (`examNO`), + KEY `stuid` (`stuID`), + CONSTRAINT `examNO` FOREIGN KEY (`examNO`) REFERENCES `stuexam` (`examNO`), + CONSTRAINT `stuid` FOREIGN KEY (`stuID`) REFERENCES `stuinfo` (`stuNo`) +); +insert into stuinfo +values ('s2501', '张秋利', '男', 20, '美国硅谷', 1), + ('s2502', '李斯文', '女', 18, '湖北武汉', 2), + ('s2503', '马文才', '男', 18, '湖南长沙', 3), + ('s2504', '欧阳俊雄', '女', 21, '湖北武汉', 4), + ('s2505', '梅超风', '男', 20, '湖北武汉', 5), + ('s2506', '陈旋风', '男', 19, '美国硅谷', 6); +insert into stuexam +values (1, 's2501', 50, 70), + (2, 's2502', 60, 65), + (3, 's2503', 86, 70), + (4, 's2504', 40, 80), + (5, 's2505', 70, 85), + (6, 's2506', 85, 90); +insert into stumarks +values (1, 's2501', 88), + (2, 's2501', 92), + (3, 's2501', 53), + (4, 's2502', 60), + (5, 's2502', 99), + (6, 's2503', 82); +# 在如图的数据表上完成以下题目 +# +# 1.查询出年龄比班上平均年龄大的学生的信息 +select * +from stuinfo +where stuAge > (select avg(stuAge) from stuinfo); +# 2.查询出每个学生的学号,姓名,性别和选修课程的最高分(stuMarks) +select stuNO, stuName, stuSex, max(score) +from stuinfo inf + left join stumarks ma on inf.stuNo = ma.stuID +group by stuNo; +# 3.查询出每个学生的学号,姓名,性别和考试平均分(stuExam) +select inf.stuNo, stuName, stuSex, (writtenExam+labExam)/2 num +from stuinfo inf + left join stuexam ex on inf.stuNo = ex.stuNO +group by stuNo; +# 4.查询性别是男并且年龄大于等于20的学生的信息(用两种方法实现:普通查询和子查询) +select * +from stuinfo +where stuSex = '男' + and stuAge >= 20; +select * +from stuinfo +where stuAge in (select stuAge from stuinfo where stuage >= 20) + and stuSex in (select stuSex from stuinfo where stuSex = '男'); +# 5.查询出年龄比所有男生年龄都大的女生的信息 +select * +from stuinfo +where stuAge > (select max(stuAge) from stuinfo where stuSex = '男'); +# 6.查询出所有选修课程都及格的学生的信息 (stuMarks) +select inf.* +from stuinfo inf,(select stuID from stumarks group by stuID having min(score)>=60) num +where inf.stuNo = num.stuID; +# 7.查询出参加考试的学生的信息(用表连接,in二种方法做)(stuMarks) +select inf.* +from stuinfo inf + left join stumarks s on inf.stuNo = s.stuID +where score is not null; +# 8.查询出没有参加考试的学生的信息(用表连接,in二种方法做)(stuMarks) +select inf.* +from stuinfo inf + left join stumarks s on inf.stuNo = s.stuID +where score is null; +# 9.将有一门成绩成绩大于90分的学生的基本信息查询出来(stuMarks) +select inf.* +from stuinfo inf + inner join stumarks s on inf.stuNo = s.stuID +where score in (select score from stumarks where score > 90); +# 10.查询出平均成绩在80分以上的学生的基本信息(stuMarks) +select s.*, avg(score) num +from stumarks ma + inner join stuinfo s on ma.stuID = s.stuNo +group by ma.stuID +having num > 80; +# 11.查询出某同学所有考试成绩比“张秋利”同学所有分数都高的学生基本信息(stuMarks) +select * +from (select *, max(score) num + from stuinfo inf + inner join stumarks ma on inf.stuNo = ma.stuID + group by stuID) maxsc +where num > (select max(score) from stumarks where stuID = 's2501'); +# 12.查询出某同学所有考试成绩只需要比“张秋利”同学某个分数高的学生基本信息(stuMarks) +select s2.* +from stumarks + inner join stuinfo s2 on stumarks.stuID = s2.stuNo +where score > (select min(score) + from stumarks + inner join stuinfo s on stumarks.stuID = s.stuNo + where stuName = '张秋利') + and stuName != '张秋利' +group by stuNo; +# 13.查询班上比所有男生年龄都要大的女生的信息 +select * +from stuinfo +where (stuage > (select max(stuAge) from stuinfo where stuSex = '男')) + and stuSex = '女'; +# 14.查询出只是比某个男生年龄大的女生的信息 +select * +from stuinfo +where (stuage > (select min(stuAge) from stuinfo where stuSex = '男')) + and stuSex = '女'; +``` + -- Gitee