diff --git "a/19\351\231\210\345\246\203/20230227\345\205\263\350\201\224\346\237\245\350\257\242.md" "b/19\351\231\210\345\246\203/20230227\345\205\263\350\201\224\346\237\245\350\257\242.md" deleted file mode 100644 index 42667a4db37d8522631c32d4d245e1ff4889a711..0000000000000000000000000000000000000000 --- "a/19\351\231\210\345\246\203/20230227\345\205\263\350\201\224\346\237\245\350\257\242.md" +++ /dev/null @@ -1,302 +0,0 @@ -# 笔记 - -```sql -1、关联查询的结果一共有7种: -两个表的记录分为四种: -①A表中的记录能在B表中找到对应的记录 -②A表中的记录在B表中找不到对应的记录 -③B表中的记录可以在A表找到对应的记录 -④B表中的记录在A表中找不到对应的记录 - -(1)A∩B ①③ -(2)A ①② -(3)A-A∩B ② -(4)B ③④ -(5)B-A∩B ④ -(6)A∪B ①②③④ -(7)A∪B-A∩B ②④ - -2、两个表要一起查询,要有前提条件:有关联 -就是有相同逻辑意义和数据类型的字段。 - -3、如何实现7种查询结果 -(1)内连接 inner join -(2)外连接 outer join -左外连接 left outer join 或 left join -右外连接 right outer join 或 right join -全外连接 full outer join 或 full join -- union 代替 - -但是,mysql不支持全外连接,没有full join。 -mysql使用union关键字合并其他的查询结果实现全外连接的效果。 - -内连接 ==> A∩B -左连接 ==> A 或 A-A∩B -右连接 ==> B 或 B-A∩B -全外连接 ==> A∪B 或 A∪B - A∩B - 左连接的A union 右连接的B 得到 A∪B - 左连接的A-A∩B union 右连接B-A∩B 得到 A∪B - A∩B - -4、内连接 inner join -A表 inner join B表 on 关联条件 -*/ - -#查询员工表的员工姓名,和部门编号,部门表的部门名称 -#不显示那些 没有分配部门的员工,也不包括那些没有员工的部门 - --- 重名问题的产生 -/* -Column 'did' in field list is ambiguous 有重名问题 -原因:did没有指定是哪个表的, -*/ - --- 笛卡尔积的产生 -/* -上面的sql错误,结果出现了一种现象:笛卡尔积 -原因:无关联条件 -*/ - -``` - - - - - -# 作业 - -```sql --- 1. - create database demo charset utf8; --- 2. **数据库的表结构** - use demo; --- 表(一)Student (学生表) --- --- | 属性名 | 数据类型 | 可否为空 | 含义 | --- | --------- | ------------ | -------- | ------------ | --- | Sno | varchar (20) | 否 | 学号(主码) | --- | Sname | varchar (20) | 否 | 学生姓名 | --- | Ssex | varchar (20) | 否 | 学生性别 | --- | Sbirthday | datetime | 可 | 学生出生年月 | --- | Class | varchar (20) | 可 | 学生所在班级 | -create table Student( - Sno varchar(20) primary key comment '学号', - Sname varchar(20) not null comment '学生姓名', - Ssex varchar(20) not null comment '学生性别', - Sbirthday datetime comment '学生出生年月', - Class varchar(20) comment '学生所在班级' -); - --- 表(二)Course(课程表) --- --- | 属性名 | 数据类型 | 可否为空 | 含义 | --- | ------ | ------------ | -------- | ---------------- | --- | Cno | varchar (20) | 否 | 课程号(主码) | --- | Cname | varchar (20) | 否 | 课程名称 | --- | Tno | varchar (20) | 否 | 教工编号(外码) | -create table Course( - Cno varchar(20) primary key comment '课程号', - Cname varchar(20) not null comment '课程名称 ', - Tno varchar(20) not null comment '教工编号', - foreign key (Tno) references Teacher (Tno) -); - --- 表(三)Score(成绩表) --- --- | 属性名 | 数据类型 | 可否为空 | 含义 | --- | -------------- | ------------ | -------- | -------------- | --- | Sno | varchar (20) | 否 | 学号(外码) | --- | Cno | varchar (20) | 否 | 课程号(外码) | --- | Degree | Decimal(4,1) | 可 | 成绩 | --- | 主码:Sno+ Cno | | | | -create table Score( - Sno varchar(20) not null comment '学号', - Cno varchar(20) not null comment '课程号', - Degree Decimal(4, 1) comment '成绩', - foreign key (Sno) references Student (Sno), - foreign key (Cno) references Course (Cno), - primary key (Sno, Cno) -); - --- 表(四)Teacher(教师表) --- --- | 属性名 | 数据类型 | 可否为空 | 含义 | --- | --------- | ------------ | -------- | ---------------- | --- | Tno | varchar (20) | 否 | 教工编号(主码) | --- | Tname | varchar (20) | 否 | 教工姓名 | --- | Tsex | varchar (20) | 否 | 教工性别 | --- | Tbirthday | datetime | 可 | 教工出生年月 | --- | Prof | varchar (20) | 可 | 职称 | --- | Depart | varchar (20) | 否 | 教工所在部门 | -create table Teacher( - Tno varchar(20) primary key not null comment '教工编号', - Tname varchar(20) not null comment '教工姓名', - Tsex varchar(20) not null comment '教工性别', - Tbirthday datetime comment '教工出生年月', - Prof varchar(20) comment '职称', - Depart varchar(20) not null comment '教工所在部门' -); - --- 表(一)Student --- --- | Sno | Sname | Ssex | Sbirthday | class | --- | ---- | ----- | ---- | --------- | ----- | --- | 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 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'); - --- 表(二)Course --- --- | Cno | Cname | Tno | --- | ----- | ---------- | ---- | --- | 3-105 | 计算机导论 | 825 | --- | 3-245 | 操作系统 | 804 | --- | 6-166 | 数字电路 | 856 | --- | 9-888 | 高等数学 | 831 | -insert into Course values - ('3-105', '计算机导论', '825'), - ('3-245', '操作系统', '804'), - ('6-166', '数字电路', '856'), - ('9-888', '高等数学', '831'); - --- 表(三)Score --- --- | Sno | Cno | Degree | --- | ---- | ----- | ------ | --- | 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 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'); - --- 表(四)Teacher --- --- | Tno | Tname | Tsex | Tbirthday | Prof | Depart | --- | ---- | ----- | ---- | --------- | ------ | ---------- | --- | 804 | 李诚 | 男 | 1958-12-2 | 副教授 | 计算机系 | --- | 856 | 张旭 | 男 | 1969-3-12 | 讲师 | 电子工程系 | --- | 825 | 王萍 | 女 | 1972-5-5 | 助教 | 计算机系 | --- | 831 | 刘冰 | 女 | 1977-8-14 | 助教 | 电子工程系 | -insert into Teacher values - (804, '李诚', '男', '1958-12-2', '副教授', '计算机系'), - (856, '张旭', '男', '1969-3-12', '讲师', '电子工程系'), - (825, '王萍', '女', '1972-5-5', '助教', '计算机系'), - (831, '刘冰', '女', '1977-8-14', '助教', '电子工程系'); - --- 3. **数据库中的数据**: --- --- -- 1,查询所有学生,都学了哪些课程,要显示学生信息和课程信息/ -SELECT Student.*,cname FROM Student LEFT JOIN Score ON Student.sno = Score.sno LEFT JOIN Course ON Score.cno = Course.cno; - --- -- 2,查询没有学生的教师的所有信息 -SELECT teacher.* FROM teacher LEFT JOIN Course ON teacher.tno = course.tno LEFT JOIN score ON score.cno = course.cno LEFT JOIN student ON student.sno = score.sno WHERE student.sno IS NULL; - --- 4. 查询 --- --- ① 查询Score表中的最高分的学生学号和课程号。 -SELECT sno, cno FROM score WHERE degree = ( SELECT max( degree ) FROM score ); - --- ② 查询所有学生的Sname、Cno和Degree列。 -SELECT Sname, Cno, Degree FROM Student INNER JOIN Score ON student.sno = score.sno; - --- ③ 查询所有学生的Sno、Cname和Degree列。 -SELECT Sno,Cname,Degree FROM Score INNER JOIN course ON score.cno = course.cno; - --- ④ 查询所有学生的Sname、Cname和Degree列。 -SELECT sname,cname,degree FROM student INNER JOIN score ON student.sno = score.sno INNER JOIN course ON score.cno = course.cno; - --- ⑤ 查询“95033”班学生的平均分。 -SELECT class,avg(Degree) FROM Score INNER JOIN Student ON Score.Sno = Student.Sno WHERE class = 95033; - --- ⑥ 查询选修“3-105”课程的成绩高于“109”号同学成绩的所有同学的记录。 -SELECT * FROM Score WHERE Degree >( SELECT Degree FROM Score WHERE Sno = '109' AND Cno = '3-105' ) AND Cno = '3-105'; - --- ⑦ 查询score中选学多门课程的同学中分数为非最高分成绩的记录。 -SELECT * FROM Score a WHERE Degree < ( SELECT MAX( degree ) FROM Score b WHERE a.Cno = b.Cno ) AND Sno IN ( SELECT Sno FROM Score GROUP BY Sno HAVING count(*) > 1 ); - --- ⑧ 查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。 -SELECT * FROM score WHERE degree > ( SELECT degree FROM score WHERE score.sno = 109 AND score.cno = '3-105' ); - --- ⑨ 查询和学号为108的同学同年出生的所有学生的Sno、Sname和Sbirthday列。 -SELECT sno,sname,sbirthday FROM student WHERE sbirthday = ( SELECT sbirthday FROM student WHERE sno = 108 ); - --- ⑩ 查询“张旭“教师任课的学生成绩。 -SELECT Sno,Degree FROM Score WHERE -Cno =( SELECT Cno FROM CourseINNER JOIN Teacher ON Course.Tno = Teacher.Tno WHERE Tname = '张旭' ); - --- 11 查询选修某课程的同学人数多于5人的教师姓名。 -SELECT Tname FROM Teacher WHERE -Tno = ( SELECT Tno FROM Course WHERE - Cno = ( SELECT Cno FROM Score GROUP BY Cno HAVING COUNT( Cno ) > 5 )); - --- 12 查询出“计算机系“教师所教课程的成绩表。 -SELECT score.sno,score.cno,degree FROM score - LEFT JOIN course ON score.cno = course.cno - LEFT JOIN teacher ON course.tno = teacher.tno -WHERE depart = '计算机系'; - --- 13 查询“计算机系”与“电子工程系“不同职称的教师的Tname和Prof。 -SELECT tname,prof FROM teacher WHERE prof IN ( SELECT DISTINCT prof FROM teacher ); - --- 14 查询选修编号为“3-105“课程且成绩至少高于选修编号为“3-245”的同学的Cno、Sno和Degree,并按Degree从高到低次序排序。 -SELECT score.cno,score.sno,score.degree FROM score INNER JOIN course ON score.cno = course.cno AND score.cno = '3-105' AND score.degree > ( SELECT max( degree ) FROM score WHERE score.cno = '3-245' ) ORDER BY score.degree DESC; - --- 15 查询选修编号为“3-105”且成绩高于选修编号为“3-245”课程的同学的Cno、Sno和Degree. -SELECT score.cno,score.sno,score.degree FROM score INNER JOIN course ON score.cno = course.cno AND score.cno = '3-105' AND score.degree > ( SELECT max( degree ) FROM score WHERE score.cno = '3-245' ); - --- 16 查询成绩比该课程平均成绩低的同学的成绩表。 -SELECT * FROM Score a WHERE Degree < ( SELECT avg( Degree ) FROM score b WHERE a.Cno = b.Cno ); - --- 17 查询所有任课教师的Tname和Depart. -SELECT tname,depart FROM teacher; - --- 18 查询所有未讲课的教师的Tname和Depart -SELECT Tname,Depart FROM Teacher LEFT JOIN Course ON Teacher.Tno = Course.TnoLEFT JOIN Score ON Course.Cno = Score.Cno WHERE Score.Cno IS NULL; - --- 19 查询“男”教师及其所上的课程。 -SELECT tname,cname FROM teacher LEFT JOIN course ON teacher.tno = course.tno WHERE tsex = '男'; - --- 20 查询最高分同学的Sno、Cno和Degree列。 -SELECT sno,cno,degree FROM score WHERE degree = ( SELECT max( degree ) FROM score ); - --- 21 查询和“李军”同性别的所有同学的Sname. -SELECT sname FROM student WHERE ssex = ( SELECT ssex FROM student WHERE sname = '李军' ); - --- 22 查询和“李军”同性别并同班的同学Sname. -SELECT sname student WHERE ssex = ( SELECT ssex FROM student WHERE sname = '李军' ) AND class = ( SELECT class FROM student WHERE sname = '李军' ); - --- 23 查询所有选修“计算机导论”课程的“男”同学的成绩表。 -SELECT score.* FROM score LEFT JOIN courseon score.cno = course.cno LEFT JOIN studenton score.sno = student.sno WHERE score.cno =( SELECT course.cno FROM course WHERE cname = '计算机导论' ); - - - -``` - diff --git "a/19\351\231\210\345\246\203/20230306\345\255\220\346\237\245\350\257\242.md" "b/19\351\231\210\345\246\203/20230306\345\255\220\346\237\245\350\257\242.md" deleted file mode 100644 index 4dc244c7d1e42187d36bd2f78b7d3f4c72e1bb0d..0000000000000000000000000000000000000000 --- "a/19\351\231\210\345\246\203/20230306\345\255\220\346\237\245\350\257\242.md" +++ /dev/null @@ -1,231 +0,0 @@ -# 笔记 - -```sql -select ① from ③ where ②; - -# 形式一,select后面嵌套子查询 -#(1)在“t_employee”表中查询每个人薪资和公司平均薪资的差值, -#并显示员工薪资和公司平均薪资相差5000元以上的记录。 --- select salary-avg(salary) from t_employee; 错误,只有一条 -select avg(salary) from t_employee; - -select ename,salary,salary-(select avg(salary) from t_employee) 差值 from t_employee -where abs(salary-(select avg(salary) from t_employee))>5000; -- where 后面不支持聚合函数和别名,having支持聚合也支持别名 - -#(2)在“t_employee”表中查询每个部门平均薪资和公司平均薪资的差值。 -# 第一步,查询每个部门的平均薪资 -select did,avg(salary),avg(salary)-(select avg(salary) from t_employee) 差值 from t_employee group by did; -# 第二步,查询全公司的平均薪资 - - -# 形式二,在where/having 后面做条件 -#(1)在“t_employee”表中查询薪资最高的员工姓名(ename)和薪资(salary)。 -# 第一步,查询最高的薪资是多少钱 -select max(salary) from t_employee; -# 第二步,查询谁的薪资等于最高的这个值 -select * from t_employee where salary= (select max(salary) from t_employee); - - -#(2)在“t_employee”表中查询比全公司平均薪资高的男员工姓名和薪资。 -# 第一步,查询全公司平均的薪资是多少 -select avg(salary) from t_employee; - -# 第二步,查询谁的薪资>平均薪资 && gender = '男' -select * from t_employee -where gender = '男' - and salary > (select avg(salary) from t_employee); - - -#(3)在“t_employee”表中查询和“白露”,“谢吉娜”同一部门的员工姓名和电话。 -# 第一步,查询“白露”,“谢吉娜”的部门编号 -select did from t_employee where ename = '白露' or ename = '谢吉娜'; - -# 第二步,谁的部门编号和她们两一样 --- select ename,tel from t_employee --- where did = (select did from t_employee where ename = '白露' or ename = '谢吉娜'); --- 1242 - Subquery(子查询) returns (返回) more than 1 row (超过1行) - -select ename,tel from t_employee -where did in(select did from t_employee where ename = '白露' or ename = '谢吉娜'); - - -select ename,tel from t_employee -where did =any(select did from t_employee where ename = '白露' or ename = '谢吉娜'); - -/* - 当子查询放在where 、 having 后面当条件用是,有几种情况 - ① 单列单个值,可以直接用>,<,<=...!=,这些比较运算符 - ② 单列多个值,要用in,not in 这种集合的比较 - ③ 单列多个值,可以用>,<,<=...!=,比较运算符,搭配any,all 这些关键字,一起使用 - - -*/ - - - -# 形式三,在from后面,形成一个临时表,必须加一个别名 -#(1)查询每个部门的部门编号、部门名称,平均薪资, -# 方案一,先联表,再分组 -select b.did,dname,avg(salary) -from t_employee a right join t_department b on a.did = b.did -group by b.did; - -# 方案二,先分组,再联表 -select b.did,dname,num -from -(select did,avg(salary) num from t_employee group by did) as avgtable -right join t_department b on avgtable.did = b.did -order by did; - -/* - 子查询的结果: - 单列单个值:可以放在select 后,也可以放where/having之后 - 单列多个值:where后,或having后 ,不用直接用<,=,>= 这种单纯的比较运算符。但可以用搭配any(任意一个),all(所有的)等关键字一起使用。还可以用in,not in这种表达式 - - - 多列时,只能当临时表来表用,放在from后面,而且必须,给他取个别名 - - -*/ -``` - - - -# 作业 - - - -```sql - ---建表 - -create database xuexiaode charset utf8; - -use xuexiaode; - -create table stuinfo( -stuNO varchar(10), -stuName varchar(10), -stuSex varchar(1), -stuAge int, -stuAddress varchar(10), -stuSeat int -); -create table stuExam( -examNO INT, -stuNO varchar(10), -writtenExam INT, -labExam int -); - -create table stuMarks( -examNo int, -stuID varchar(10), -score int -); - -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',93), -(5,'s2502',99), -(6,'s2503',82); --- --- --- 在如图的数据表上完成以下题目 --- --- 1.查询出年龄比班上平均年龄大的学生的信息 - -select * from stuinfo where (select avg(stuAge) from stuinfo) < stuAge; - --- --- 2.查询出每个学生的学号,姓名,性别和选修课程的最高分(stuMarks) - -select stuNO,stuName,stuSex,sc from stuinfo left join (select stuID,max(score) sc from stuMarks GROUP BY stuID) b on stuinfo.stuNO = b.stuID; --- --- 3.查询出每个学生的学号,姓名,性别和考试平均分(stuExam) -select stuinfo.stuNO,stuName,stuSex,aug from stuinfo left join (select stuNO,(writtenExam + labExam)/2 aug from stuExam) lijunyang on stuinfo.stuNO=lijunyang.stuNO; --- --- 4.查询性别是男并且年龄大于等于20的学生的信息(用两种方法实现:普通查询和子查询) - -select * from stuinfo where stuSex = '男' and stuAge >= 20; - -select * from stuinfo where stuSex in (select stuSex from stuinfo where stuSex = '男') and stuAge in (select stuAge from stuinfo where stuAge >= 20) - - --- 5.查询出年龄比所有男生年龄都大的女生的信息 - -select * from stuinfo where stuAge >any(select stuAge from stuinfo where stuSex = '男') and stuSex = '女'; - --- --- 6.查询出所有选修课程都及格的学生的信息 (stuMarks) - - -select * from stuinfo left join (select stuID,min(score) li from stuMarks GROUP BY stuID) aug on aug.stuID = stuinfo.stuNO where li>= 60; --- --- 7.查询出参加考试的学生的信息(用表连接,in二种方法做)(stuMarks) - -select distinct b.* from stumarks a left join stuinfo b on a.stuid=b.stuno; -select from stuinfo where stuno in(select distinct stuid from stumarks); -select * from stuinfo left join stuMarks on stuinfo.stuNo = stuMarks.stuID where score is not null; select * from stuinfo where stuNO in (select stuID from stuMarks GROUP BY stuID); - - --- --- 8.查询出没有参加考试的学生的信息(用表连接,in二种方法做)(stuMarks) - -select * from stuinfo left join stuMarks on stuinfo.stuNO = stuMarks.stuID where score is null; - - -select * from stuinfo where stuNO not in (select stuID from stuMarks GROUP BY stuID); - --- --- 9.将有一门成绩成绩大于90分的学生的基本信息查询出来(stuMarks) - -select * from stuinfo where stuno in(select distinct stuid from stumarks wherescore>90); --- --- 10.查询出平均成绩在80分以上的学生的基本信息(stuMarks) - -select * from stuinfo left join (select stuNO,(writtenExam + labExam)/2 aug from stuExam) li on li.stuNO = stuinfo.stuNO where aug >=80; - --- --- 11.查询出某同学所有考试成绩比“张秋利”同学所有分数都高的学生基本信息(stuMarks) - -select * from stuinfo where stuno in(select stuid from stumarks where score> all(select score from stumarks where stuid =(select stuno from stuinfo where stuname ='张秋利'))); - --- --- 12.查询出某同学所有考试成绩只需要比“张秋利”同学某个分数高的学生基本信息(stuMarks) - -select * from stuMarks right join stuinfo on stuinfo.stuNo = stuMarks.stuID where score > (select min(score) from stuMarks left join stuinfo on stuinfo.stuNo = stuMarks.stuID where stuName = '张秋利') ; - - --- --- 13.查询班上比所有男生年龄都要大的女生的信息 - -select * from stuinfo where stusex ='女'and stuage > (select max(stuage) from stuinfo where stusex='男'); - - --- --- 14.查询出只是比某个男生年龄大的女生的信息 - -select * from stuinfo where stuSex='女' and stuAge >= (select min(stuAge) from stuinfo where stuSex='男'); - - -``` - diff --git "a/19\351\231\210\345\246\203/20230308\347\273\203\344\271\240\344\275\234\344\270\232.md" "b/19\351\231\210\345\246\203/20230308\347\273\203\344\271\240\344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..7fec8d1abdd0360b15e109debcadd548f20c8c11 --- /dev/null +++ "b/19\351\231\210\345\246\203/20230308\347\273\203\344\271\240\344\275\234\344\270\232.md" @@ -0,0 +1,189 @@ +# 笔记 + +```sql +关联查询 +#演示左连接 +/* +(2)A +(3)A-A∩B +*/ +/* +观察数据: +t_employee 看成A表 +t_department 看成B表 +此时t_employee (A表)中有 李红和周洲的did是NULL,没有对应部门, + t_department(B表)中有 测试部,在员工表中找不到对应记录的。 +*/ +#查询所有员工,包括没有指定部门的员工,他们的姓名、薪资、部门编号、部门名称 +SELECT ename,salary,t_department.did,dname +FROM t_employee LEFT JOIN t_department +ON t_employee.did = t_department.did; +#查询的是A结果 A left join B + +#查询没有部门的员工信息 +SELECT ename,salary,t_department.did,dname +FROM t_employee LEFT JOIN t_department +ON t_employee.did = t_department.did +WHERE t_employee.did IS NULL; +#查询的结果是A - A∩B +#此时的where条件,建议写子表的关联字段is null,这样更准确一点。 +#如果要建外键,它们肯定有子表和父表的角色,写子表的关联字段is null +#因为父表中这个字段一般是主键,不会为null。 + + +#2、on子句 +/* +(1)on必须配合join使用 +(2)on后面只写关联条件 +所谓关联条件是两个表的关联字段的关系 +(3)有n张表关联,就有n-1个关联条件 +两张表关联,就有1个关联条件 +三张表关联,就有2个关联条件 +*/ +SELECT * +FROM t_employee INNER JOIN t_department +ON t_employee.did = t_department.did; #1个关联条件 + +#查询员工的编号,姓名,职位编号,职位名称,部门编号,部门名称 +#需要t_employee员工表,t_department部门表,t_job职位表 +SELECT eid,ename,t_job.jid,t_job.jname, `t_department`.`did`,`t_department`.`dname` +FROM t_employee INNER JOIN t_department INNER JOIN t_job +ON t_employee.did = t_department.did AND t_employee.job_id = t_job.jid; + + +#3、where子句,在查询结果中筛选 +#查询女员工的信息,以及女员工的部门信息 +SELECT * +FROM t_employee INNER JOIN t_department +ON t_employee.did = t_department.did +WHERE gender = '女'; + +#4、group by分组 +#查询所有员工的平均薪资 +SELECT AVG(salary) FROM t_employee; + +#查询每一个部门的平均薪资 +SELECT did,ROUND(AVG(salary),2 ) +FROM t_employee +GROUP BY did; + +#查询每一个部门的平均薪资,显示部门编号,部门的名称,该部门的平均薪资 +SELECT t_department.did,dname,ROUND(AVG(salary),2 ) +FROM t_department LEFT JOIN t_employee +ON t_department.did = t_employee.did +GROUP BY t_department.did; + +#查询每一个部门的平均薪资,显示部门编号,部门的名称,该部门的平均薪资 +#要求,如果没有员工的部门,平均薪资不显示null,显示0 +SELECT t_department.did,dname,IFNULL(ROUND(AVG(salary),2),0) +FROM t_department LEFT JOIN t_employee +ON t_department.did = t_employee.did +GROUP BY t_department.did; + +#查询每一个部门的女员工的平均薪资,显示部门编号,部门的名称,该部门的平均薪资 +#要求,如果没有员工的部门,平均薪资不显示null,显示0 +SELECT t_department.did,dname,IFNULL(ROUND(AVG(salary),2),0) +FROM t_department LEFT JOIN t_employee +ON t_department.did = t_employee.did +WHERE gender = '女' +GROUP BY t_department.did; +``` + + + +# 作业 + +```mysql + +CREATE DATABASE dingdan charset utf8; +drop database dingdan; +use dingdan; + +CREATE TABLE order1( +orderID INT, +orderDate date + +); + +INSERT into order1 VALUES +(1,'2008-01-12 00:00:00.000'), +(2,'2008-02-10 00:00:00.000'), +(3,'2008-02-15 00:00:00.000'), +(4,'2008-03-10 00:00:00.000'); + +CREATE TABLE order2( +itemID INT, +orderid INT, +itemType VARCHAR(20), +itemName VARCHAR(20), +theNumber INT, +theMoney int + +); +drop table order2; +INSERT INTO order2 VALUES +(1,1,'文具','笔',72,2), +(2,1,'文具','尺',10,1), +(3,1,'体育用品','篮球',1,56), +(4,2,'文具','笔',36,2), +(5,2,'文具','固体胶',20,3), +(6,2,'日常用品','透明胶',2,1), +(7,2,'体育用品','羽毛球',20,3), +(8,3,'文具','订书机',20,3), +(9,3,'文具','订书针',10,3), +(10,3,'文具','裁纸刀',5,5), +(11,4,'文具','笔',20,2), +(12,4,'文具','信纸',50,1), +(13,4,'日常用品','毛巾',4,5), +(14,4,'日常用品','透明胶',30,1), +(15,4,'体育用品','羽毛球',20,3); + + + + +-- 1.查询所有的订单的订单的编号,订单日期,订购产品的类别和订购的产品名称,订购数量和订购单价 +-- +SELECT * FROM order2: + +SELECT * FROM order1; + +SELECT order1.orderID,order1.orderDate,order2.itemType,order2.itemName,order2.theNumber,order2.theMoney FROM order2 LEFT JOIN order1 on order1.orderID = order2.orderid ; + + +-- 2.查询订购数量大于50的订单的编号,订单日期,订购产品的类别和订购的产品名称 +-- +SELECT order1.orderID,order1.orderDate,order2.itemType,order2.itemName FROM order2 LEFT JOIN order1 on order1.orderID = order2.orderid WHERE (order2.theNumber) > 50; + +-- 3.查询所有的订单的订单的编号,订单日期,订购产品的类别和订购的产品名称,订购数量和订购单价以及订购总价 +-- +SELECT order1.orderID,order1.orderDate,order2.itemType,order2.itemName,order2.theNumber,order2.theMoney,(order2.theNumber*order2.theMoney) FROM order2 LEFT JOIN order1 on order1.orderID = order2.orderid ; + + + +-- 4.查询单价大于等于5 或者 数量大于等于50的订单的订单的编号,订单日期,订购产品的类别和订购的产品名称,订购数量和订购单价以及订购总价 +-- +SELECT order1.orderID,order1.orderDate,order2.itemType,order2.itemName,order2.theNumber,order2.theMoney,(order2.theNumber*order2.theMoney) FROM order2 LEFT JOIN order1 on order1.orderID = order2.orderid WHERE (order2.theMoney) >= 5 OR (order2.theNumber) >= 50; + +-- 5.查询每个订单分别订购了几个产品,例如: +-- 编号 订购产品数 +-- 1 3 +-- 2 4 + +SELECT order1.orderID as 编号,order2.theNumber 订购产品数 FROM order2 LEFT JOIN order1 on order1.orderID = order2.orderid; + +-- +-- 6.查询每个订单里的每个类别的产品分别订购了几次和总数量,例如: +-- +-- 订单编号 产品类别 订购次数 总数量 +-- +-- 1 文具 2 82 +-- 1 体育用品 1 1 +-- 2 文具 2 56 +-- 2 体育用品 1 2 +-- 2 日常用品 1 20 + +SELECT order1.orderID as 订单编号,order2.itemType as 产品类别 ,order2.theNumber as 订购次数 ,sum(order2.theNumber) as 总数量 FROM order2 LEFT JOIN order1 on order1.orderID = order2.orderid ; + + +``` + diff --git "a/19\351\231\210\345\246\203/20230308\350\257\225\345\215\267\344\275\234\344\270\232.md" "b/19\351\231\210\345\246\203/20230308\350\257\225\345\215\267\344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..dfb1554f71d885c3bb186a1d5b514bd0c032e639 --- /dev/null +++ "b/19\351\231\210\345\246\203/20230308\350\257\225\345\215\267\344\275\234\344\270\232.md" @@ -0,0 +1,204 @@ +```mysql +1. -- # MySQL基础结课考试 + -- ## 考试时间 120 分钟 总分:100分 + -- **场景**: + -- 你在一个软件公司上班,今天公司接一个新业务。要用MySQL给一个小说网站设计一个数据库。 + -- **数据库名**:xiaoshuo + -- 该数据库里有四张表:作家信息表 ( author )、作家等级信息表 ( vip )、小说作品信息表 ( story )、小说作品类型表 ( type ) + -- ### 1、相关表结构 + -- 1. 作家信息表 ( author ) (4分) +-- | 字段名称 | 数据类型 | 说明及要求 | +-- | ------------ | ------------| -------------------------------| +-- | author_id | int | 作家编号,主键 | +-- | author_name | varchar(20) | 作家姓名、非空、不能重复 | +-- | credits | int | 积分 | +-- | vip_id | varchar(20) | 等级编号,非空、外键关联等级信息表 | + +-- | -- 2. 作家等级信息表 ( vip ) (3分) +-- | 字段名称 | 数据类型 | 说明及要求 | +-- | -------- | ----------- | ------------------------- | +-- | vip_id | varchar(20) | 等级编号,主键 | +-- | vip_name | varchar(20) | 等级名称,非空,不能重复 | +-- | | | | + +-- 3. 小说作品信息表 ( story )(4分) +-- | 字段名称 | 数据类型 | 说明及要求 | +-- | ------------ | ----------- | ----------------------------- | +-- | story_id | int | 作品编号,主键,自增 | +-- | author_id | int | 作家编号,外键,关联作家信息表 | +-- | type_id | varchar(20) | 类型编号,外键,关键作品类型表 | +-- | story_name | varchar(50) | 作品名称 | +-- | views_number | int | 浏览量 | +-- | | | | +-- 4. 小说作品类型表 ( type )(2分) +-- | 字段名称 | 数据类型 | 说明及要求 | +-- | --------- | ----------- | ------------------------ | +-- | type_id | varchar(20) | 类型编号,主键 | +-- | type_name | varchar(20) | 类型名称,非空,不能重复 | +-- | | | | +-- ### 2、对应的表数据 +-- 1. 作家信息表 (4分) + +-- | 作家编号 | 作家名称 | 积分 | 等级编号 | +-- | -------- | :------: | :------: | :---------------------: | +-- | 1001 | 朱逸群 | 600 | VIP01 | +-- | 1002 | 范建 | 8510 | VIP04 | +-- | 1003 | 史珍香 | 981 | VIP02 | +-- | 1004 | 范统 | 2364 | VIP02 | +-- | 1005 | 杜子腾 | 257 | VIP01 | +-- | 1006 | 刘产 | 678 | VIP02 | +-- | 1007 | 杜琦燕 | 438 | VIP03 | + +-- 2. 等级信息表(2分 + +-- | 等级编号 | 等级名称 | +-- | :------: | :------:| +-- | VIP01 | 青铜作家 | +-- | VIP02 | 白银作家 | +-- | VIP03 | 黄金作家 | +-- | VIP04 | 钻石作家 | +-- 3. 小说作品信息表(5分) +-- | 作品编号 | 作家编号 | 类型编号 | 作品名称 | +-- | :------: | :------: | :------: | :-------------------- | +-- | 1 | 1002 | L03 | 母猪产后与护理师的二三事 | +-- | 2 | 1005 | L04 | 拖拉机大战蜘蛛侠 | +-- | 3 | 1003 | L01 | 这只小龙虾不正经 | +-- | 4 | 1006 | L04 | 一个爹爹三个娃 | +-- | 5 | 1006 | L01 | 皇上滚开本宫只劫财 | +-- | 6 | 1005 | L05 | 给长城贴瓷砖的小太监 | +-- | 7 | 1003 | L03 | 不科学御兽 | +-- | 8 | 1005 | L01 | 镜面管理局 | +-- | 9 | 1004 | L02 | 关于我成为灭魂师之后 | +-- | 10 | 1004 | L05 | 公子别秀 | + +-- 4. 作品类型(3分) +-- | | | +-- | :------: | :------: | +-- | L01 | 玄幻 | +-- | L02 | 奇幻 | +-- | L03 | 武侠 | +-- | L04 | 仙侠 | +-- | L05 | 都市 | +-- 3、题目 +-- > 所有题目要求使用SQL语句完成 +-- 1. 根据前面提供的表结构和表数据,创建数据库并分别创建这张四张表;并插入相关数据。(提醒:外键请注意建表顺序和插入数据的顺序) (30分) +create database xiaoshuo charset utf8; + + use xiaoshuo; + + create table author( + author_id int primary key, + author_name varchar(20) not null unique key, + credits int, + vip_id varchar(20) not null, + foreign key (vip_id) references vip(vip_id) + ); + + create table vip( + vip_id varchar(20) primary key, + vip_name varchar(20) not null unique key + ); + + create table story( + story_id int primary key auto_increment, + author_id int, + type_id varchar(20), + story_name varchar(50), + views_number int, + foreign key (author_id) references author(author_id), + foreign key (type_id) references type(type_id) + ); + + create table type( + type_id varchar(20) primary key, + type_name varchar(20) not null unique key + ); + + insert into author values + (1001,'朱逸群',600,'VIP01'), + (1002,'范建',8510,'VIP04'), + (1003,'史珍香',981,'VIP02'), + (1004,'范统',2364,'VIP02'), + (1005,'杜子腾',257,'VIP01'), + (1006,'刘产',678,'VIP02'), + (1007,'杜琦燕',438,'VIP03'); + + insert into vip values + ('VIP01','青铜作家'), + ('VIP02','白银作家'), + ('VIP03','黄金作家'), + ('VIP04','钻石作家'); + + insert into story VALUES + (1,1002,'L03','母猪产后与护理师的二三事',6541), + (2,1005,'L04','拖拉机大战蜘蛛侠',563), + (3,1003,'L01','这只小龙虾不正经',8754), + (4,1006,'L04','一个爹爹三个娃',36354), + (5,1006,'L01','皇上滚开本宫只劫财',3674), + (6,1005,'L05','给长城贴瓷砖的小太监',6541), + (7,1003,'L03','不科学御兽',1257), + (8,1005,'L01','镜面管理局',3216), + (9,1004,'L02','关于我成为灭魂师之后',1147), + (10,1004,'L05','公子别秀',2078); + + insert into type VALUES + ('L01','玄幻'), + ('L02','奇幻'), + ('L03','武侠'), + ('L04','仙侠'), + ('L05','都市'); + -- 2. 将story 表中的story_name字段类型改成varchar(40) 。(2分) + alter table story modify story_name varchar(40); + + -- 3. 在author表中增加一个性别字段 字段名:author_sex,类型: char(10),要求默认值为'男'。 (3分) + alter table author add author_sex char(10) default '男'; + + -- 4. 将作家编号为1005、1007的作家性别改为'女' 。(2分) + update author set author_sex = '女' where author_id = 1007 or author_id = 1005; + + -- 5. 作家杜子腾,写了一篇名为《拜登夸我很帅》的都市小说,有854个浏览量,请将这条信息插入到story表。(3分) + insert into story values (11,1005,'L05','拜登夸我很帅',845); + + -- 6. 《拖拉机大战蜘蛛侠》这篇小说,浏览量涨了100,请更新story表中的相关数据。(2分) + update story set views_number = views_number + 100 where story_name = '拖拉机大战蜘蛛侠'; + + -- 7. 请删除story表的中《皇上滚开本宫只劫财》这篇小说相关数据。(2分) + delete from story where story_name = '皇上滚开本宫只劫财'; + + -- 8. 查询 浏览量大于 8000的小说的作者编号和小说作品名称。(2分) + select author_id,story_name from story where views_number > 8000; + + -- 9. 查询积分大于1000 并且会员等级高于vip03的作家所有信息。(3分) + select * from author where credits > 1000 and vip_id > 'vip03'; + + -- 10. 查询姓名以杜字开头的作家的姓名,积分和等级编号。(3分) + select author_name,credits,vip_id from author where author_name like '杜%'; + + -- 11. 查询积分在100、1000之间的作家信息,以积分降序排列。 (3分) + select * from author where credits between 100 and 1000 order by credits desc; + + -- 12. 查询出小说的总浏览量,最高浏览量,最小浏览量,平均浏览量,给字段用上中文别名。(3分) + select sum(views_number) 总浏览量,max(views_number) 最高浏览量,min(views_number) 最小浏览量,avg(views_number) 平均浏览量 from story; + + -- 13. 查询各种等级的作家的平均积分和作家数量,并对查询结果使用中文别名。(3分) + select avg(credits) 平均积分,COUNT(author_id) 作家数量 from author group by vip_id; + + -- 14. 查询小说数量大于等于2的分类编号和小说数量。(4分) + select type_id,COUNT(type_id) from story group by type_id having COUNT(type_id)>= 2; + + -- 15. 查询所有小说中浏览量最少的书的作品编号、作品名称和类型编号、浏览量。(4分) + select story_id,story_name,story.type_id,views_number from story where views_number in (select min(views_number) from story); + + -- 16. 查询积分比刘产高的作者所有信息。(5分) + select * from author where credits > (select credits from author where author_name = '刘产'); + + -- 17. 查询出哪些白银作家是没有写小说的,显示这些作家的姓名、等级名称。(8分) + select author_name,c.vip_name from author a left join story b on a.author_id = b.author_id left join vip c on c.vip_id = a.vip_id where c.vip_name = '白银作家' and type_id is null; + + -- 18. 找出写过作品浏览量大于5000的作家的所有作品中浏览量不到1000的作品信息(8分) + select * from story where views_number < 1000 and author_id in (select author.author_id from author left join story on author.author_id = story.author_id where views_number >5000); + + -- 19.查询所有小说的小说编号、小说名称、浏览量、分类名称、作者姓名、作者积分、作者等级名称,结果字段要用中文别名,并按浏览量降序排列,如果浏览量一样的,再按积分降序排列。(10分) + select story_id 小说编号,story_name 小说名称,views_number 浏览量,type_id 分类名称,author.author_id 作者姓名,credits 作者积分,vip_id 作者等级 from story left join author on author.author_id = story.author_id ORDER BY views_number desc,credits desc; +``` +