diff --git "a/09 \346\241\202\346\263\275\347\205\234/DDL\345\222\214DML_\345\273\272\350\241\250\344\270\216\345\241\253\345\200\274 .md" "b/09 \346\241\202\346\263\275\347\205\234/DDL\345\222\214DML_\345\273\272\350\241\250\344\270\216\345\241\253\345\200\274 .md" index 938941b92c0f81088c6f5788db0f00c3c8f7ad90..c6a09ba60685e61d4649494072cf0c350c576e7a 100644 --- "a/09 \346\241\202\346\263\275\347\205\234/DDL\345\222\214DML_\345\273\272\350\241\250\344\270\216\345\241\253\345\200\274 .md" +++ "b/09 \346\241\202\346\263\275\347\205\234/DDL\345\222\214DML_\345\273\272\350\241\250\344\270\216\345\241\253\345\200\274 .md" @@ -284,6 +284,7 @@ B. 雇员表(emoloyee):雇员编号(empid),姓名(name),性 * ​ 雇员编号为主键; * ​ 部门编号为外键,外键约束等级为(on update cascade 和on delete set null); * ​ 性别默认为男; +<<<<<<< HEAD mysql> CREATE TABLE emoloyee( -> empid int PRIMARY key , -> name varchar(10), @@ -304,6 +305,36 @@ mysql> CREATE table salary( -> constraint fk_emoloyee -> FOREIGN KEY (empid) REFERENCES emoloyee(empid) on update cascade on delete cascade -> ) comment 'salary' ; +======= +mysql> set @@foreign_key_checks =0; +Query OK, 0 rows affected (0.00 sec) + +mysql> create table emoloyee( + -> empid int primary key, + -> name varchar(10), + -> sex varchar(1) default'男', + -> title int, + -> birthday date, + -> depid int, + -> foreign key(depid) references department(depid) on update cascade on delete set null + -> ) comment 'emoloyee'; +Query OK, 0 rows affected (0.06 sec) +C. 工资表(salary):雇员编号(empid),基本工资(basesalary),职务工资(titlesalary),扣除(deduction)。其中雇员编号为主键。 + 3、给工资表(salary)的雇员编号(empid)增加外键约束,外键约束等级为(on update cascade 和on delete cascade): +mysql> create table salary( + -> empid int primary key, + -> basesalary varchar(10), + -> titlesalary varchar(20), + -> deduction int + -> ) comment 'salary' ; +Query OK, 0 rows affected (0.05 sec) +mysql> alter table salary + -> add foreign key(empid) + -> references emoloyee(empid); +Query OK, 0 rows affected (0.01 sec) +Records: 0 Duplicates: 0 Warnings: 0 + +>>>>>>> cec424f226b2f0392650e80cf4dd7b48347071f1 添加数据: mysql> INSERT INTO department VALUES(111,'生产部',null), -> (222,'销售部',null), diff --git "a/09 \346\241\202\346\263\275\347\205\234/SELECT\350\257\255\345\217\245\345\222\214\350\277\220\347\256\227\347\254\246.md" "b/09 \346\241\202\346\263\275\347\205\234/SELECT\350\257\255\345\217\245\345\222\214\350\277\220\347\256\227\347\254\246.md" new file mode 100644 index 0000000000000000000000000000000000000000..5fdf4c81390ef277d15c9bba3dc2a7950395f905 --- /dev/null +++ "b/09 \346\241\202\346\263\275\347\205\234/SELECT\350\257\255\345\217\245\345\222\214\350\277\220\347\256\227\347\254\246.md" @@ -0,0 +1,103 @@ +## 第1题:员工表 + +```mysql +drop table if exists `employee`; +#创建employee表 +CREATE TABLE employee( + id INT, + `name` VARCHAR(20), + sex VARCHAR(20), + tel VARCHAR(20), + addr VARCHAR(50), + salary FLOAT +); + +#添加信息 +INSERT INTO employee(id,`name`,sex,tel,addr,salary)VALUES +(10001,'张一一','男','13456789000','广东韶关',10010.58), +(10002,'刘小红','女','13454319000','广东江门',12010.21), +(10003,'李四','男','0751-1234567','广东佛山',10040.11), +(10004,'刘小强','男','0755-5555555','广东深圳',15010.23), +(10005,'王艳','男',NULL,'广东广州',14050.16); +``` + +| **id** | **name** | **sex** | **tel** | **addr** | **salary** | +| ------ | -------- | ------- | ------------ | -------- | ---------- | +| 10001 | 张一一 | 男 | 13456789000 | 广东韶关 | 10010.58 | +| 10002 | 刘小红 | 女 | 13454319000 | 广东江门 | 12010.21 | +| 10003 | 李四 | 男 | 0751-1234567 | 广东佛山 | 10040.11 | +| 10004 | 刘小强 | 男 | 0755-5555555 | 广东深圳 | 15010.23 | +| 10005 | 王艳 | 女 | NULL | 广东广州 | 14050.16 | + +**要求1:**查询出薪资在12000~13000之间的员工信息。 + +**要求2:**查询出姓“刘”的员工的工号,姓名,家庭住址。 + +**要求3:**将“李四”的家庭住址改为“广东韶关” + +**要求4:**查询出名字中带“小”的员工 + +**要求5:**查询出薪资高于11000的男员工信息 + +**要求6:**查询没有登记电话号码的员工 + +**要求7:**查询薪资高于12000或者家是广东深圳、广州的男员工 + +**要求8:**查询每个员工的年薪,显示“姓名、年薪” + +```sql +查询出薪资在12000~13000之间的员工信息: +SELECT * from employee WHERE salary <=13000 and salary >=12000; +查询出姓“刘”的员工的工号,姓名,家庭住址: +SELECT id,name,addr from employee WHERE name like '刘%'; +SELECT id,name,addr from employee WHERE name like '刘__'; +将“李四”的家庭住址改为“广东韶关”: +update employee set name ="李四",addr ="广东韶关" where id =10003; + +``` + +## 第2题:国家信息表 + +countries_info表中存储了国家名称、所属大陆、面积、人口和 GDP 值。 + + + +表数据样例: + + +-------------+-----------+---------+------------+--------------+ + | name | continent | area | population | gdp | + +-------------+-----------+---------+------------+--------------+ + | Afghanistan | Asia | 652230 | 25500100 | 20343000000 | + | Albania | Europe | 28748 | 2831741 | 12960000000 | + | Algeria | Africa | 2381741 | 37100000 | 188681000000 | + | Andorra | Europe | 468 | 78115 | 3712000000 | + | Angola | Africa | 1246700 | 20609294 | 100990000000 | + +-------------+-----------+---------+------------+--------------+ + +**要求1:** 查询大国 的国家名称、人口和面积。 + +如果一个国家满足下述两个条件之一,则认为该国是 大国 : + +* 面积至少为 300万平方公里(即,3000000 km2) + +* 人口至少为 2500 万(即 25000000) + +**要求2:**查询属于亚洲的国家名称、所属大陆、面积、人口和 GDP 值 + +**要求3:**查询国土面积不足1万平方公里且人口不走10万人的国家信息 + +**要求4:**查询国家名字中包含“o“字母的国家信息 + +**要求5:**查询GDP值超过10000000000的国家信息 + +**要求6:**查询每个国家的人均贡献GDP值(GDP/人口总数)并显示为“国家名、人口、GDP值、人均贡献GDP值” + +**要求7:**查询人均贡献GDP值低于1000的国家信息。 + +**要求8:**查询每个国家的人均国土面积(面积/人口总数)并显示为“国家名、面积、人口、人均国土面积值” + +```sql + +``` + + diff --git "a/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232.docx" "b/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232.docx" new file mode 100644 index 0000000000000000000000000000000000000000..73235ab3037f2b6414001022a3554a43124a493c Binary files /dev/null and "b/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232.docx" differ diff --git "a/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232\344\270\200.md" "b/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232\344\270\200.md" new file mode 100644 index 0000000000000000000000000000000000000000..9bd091fac96c317a276d511a988bde5b7331a07c --- /dev/null +++ "b/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232\344\270\200.md" @@ -0,0 +1,159 @@ +```mysql +drop database users; +create database users charset=utf8; +use users; +create table stuinfo( +stuN0 varchar(30) primary key, +stuName varchar(25), +stuSex varchar(1), +stuAge char(30), +stuAddress varchar(20), +stuSeat int(4) +) comment'Stuinfo'; +create table stuExam( +examN0 int primary key, +stN0 varchar(30) , +wittenExam int(40), +labExam int +) comment'stuExam'; +create table stuMarks( +examN0 int primary key, +stuID varchar(30), +score int(20) +) comment'stuMarks'; +insert into stuinfo +values +("s2501","","",20,"",1), +("s2502","˹","Ů",18,"人",2), +("s2503","IJ","",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); +``` + +![ݿЧͼ](ݿЧͼ.bmp) + + + +ͼݱĿ + +1.ѯȰƽѧϢ + +```mysql +select * from stuinfo where stuAge >(select AVG(stuAge) from stuinfo); +``` + +2.ѯÿѧѧţԱѡ޿γ̵߷֣stuMarks + +```mysql +select stuN0,stuName,stuSex,score from stuinfo right join stuMarks on stuinfo.stuSeat=stuMarks.examN0 where score=(select MAX(score) from stuMarks); +``` + +3.ѯÿѧѧţԱͿƽ֣stuExam + +```mysql +select stuN0,stuName,stuSex,labExam from stuinfo inner join stuExam on stuinfo.stuSeat=stuExam.examN0; +``` + +4.ѯԱвڵ20ѧϢ(ַʵ֣ͨѯӲѯ) + +```mysql +select * from stuinfo where stuSex ="" and stuAge >=20; +select * from stuinfo where stuAge = 20 and exists (select * from stuinfo where stuSex=""); +``` + + + +5.ѯ䶼ŮϢ + +```mysql +select * from stuinfo where stuSex ="Ů" and stuAge =(select MAX(stuAge) from stuinfo); +``` + + + +6.ѯѡ޿γ̶ѧϢ stuMarks + +```mysql +select * from stuinfo right join stuMarks on stuinfo.stuSeat = stuMarks.examn0 +where score >=60; +``` + +7.ѯμӿԵѧϢñӣinַstuMarks + +```mysql +select * from stuinfo right join stuMarks on stuinfo.stuSeat=stuMarks.examN0 where stuN0 = stuID; + +select * from stuinfo,stuMarks where stuinfo.stuSeat=stuMarks.examN0 in(stuN0=stuID); +``` + + + +8.ѯûвμӿԵѧϢñӣinַstuMarks + +```mysql +select * from stuinfo,stuMarks where stuinfo.stuSeat=stuMarks.examN0 in(stuN0!=stuID); +``` + + + +9.һųɼɼ90ֵѧĻϢѯstuMarks + +```mysql +select * from stuinfo right join stuMarks on stuinfo.stuSeat = stuMarks.examn0 +where score >90; +``` + +10.ѯƽɼ80ϵѧĻϢstuMarks + +```mysql +select * from stuinfo right join stuMarks on stuinfo.stuSeat = stuMarks.examn0 +where score > 80; +``` + +11.ѯijͬѧпԳɼȡͬѧзߵѧϢstuMarks + +```mysql +select * from stuinfo inner join stuMarks on stuinfo.stuSeat = stuMarks.examn0 where score >88; +``` + + + +12.ѯijͬѧпԳɼֻҪȡͬѧijߵѧϢstuMarks + +```mysql +select * from stuinfo inner join stuMarks on stuinfo.stuSeat = stuMarks.examn0 where score >88; +``` + + + +13.ѯϱ䶼ҪŮϢ + +```mysql +select * from stuinfo where stuSex ="Ů" and stuAge =(select MAX(stuAge) from stuinfo); +``` + + + +14.ѯֻDZijŮϢ + +```mysql +select * from stuinfo where stuSex ="Ů" union select * from stuinfo where stuSex ="" order by stuAge desc; +``` + diff --git "a/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232\344\272\214.md" "b/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232\344\272\214.md" new file mode 100644 index 0000000000000000000000000000000000000000..cb24c27d05d93c3b1814310767c4901585196997 --- /dev/null +++ "b/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232\344\272\214.md" @@ -0,0 +1,95 @@ +![image-20230308102738921](ҵͼƬ.bmp) + +```mysql +create database users charset=utf8; +use users; + +create table date ( +orderid int primary key auto_increment , +orderdate date +) comment'date'; + +create table sopping( +itemid int primary key auto_increment, +orderid int(4), +itemtype varchar(30), +itemname char(14), +thenumber int(30), +themoney int(40) +)comment'sopping'; +insert into date +values +(1 ,'2008-01-12'), +(2,'2008-02-10'), +(3,'2008-02-15'), +(4,'2008-03-10'); +insert into sopping +values +(1,1,"ľ","",72,2), +(null,1,"ľ","",10,2), +(null,1,"Ʒ","",1,56), +(null,2,"ľ","",36,2), +(null,2,"ľ","彺",20,3), +(null,2,"ճƷ","͸",2,1), +(null,2,"Ʒ","ë",20,3), +(null,3,"ľ","",20,3), +(null,3,"ľ","",10,3), +(null,3,"ľ","ֽ",5,5), +(null,4,"ľ","",20,2), +(null,4,"ľ","ֽ",50,1), +(null,4,"ճƷ","ë",4,5), +(null,4,"ճƷ","͸",30,1), +(null,5,"Ʒ","ë",20,3); + +``` + +ͼʾĿ + +1.ѯеĶĶıţڣƷͶIJƷƣͶ + +```mysql +select sopping.orderid,orderdate,itemtype,itemname,thenumber,themoney from date right join sopping on date.orderid=sopping.orderid; +``` + +2.ѯ50ĶıţڣƷͶIJƷ + +```mysql +select sopping.orderid,orderdate,itemtype,itemname from sopping right join date on sopping.orderid=date.orderid where thenumber > 50; +``` + +3.ѯеĶĶıţڣƷͶIJƷƣͶԼܼ + +```mysql +select sopping.orderid,orderdate,itemtype,itemname,thenumber,themoney,(thenumber*themoney ) ܼ from date right join sopping on date.orderid=sopping.orderid; +``` + +4.ѯ۴ڵ5ߴ50ĶĶıţڣƷͶIJƷƣͶԼܼ + +```mysql +select sopping.orderid,orderdate,itemtype,itemname,thenumber,themoney,thenumber * themoney ܼ from date right join sopping on date.orderid=sopping.orderid where themoney >=5 or thenumber>50; +``` + +5.ѯÿֱ𶩹˼Ʒ磺 + Ʒ + 1 3 + 2 4 + +```mysql +select orderid,thenumber from sopping; +``` + + + +6.ѯÿÿIJƷֱ𶩹˼κ磺 + + Ʒ + + 1 ľ 2 82 + 1 Ʒ 1 1 + 2 ľ 2 56 + 2 Ʒ 1 2 + 2 ճƷ 1 20 +```mysql +select orderid ,itemtype Ʒ, orderid ,thenumber from sopping; +``` + diff --git "a/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232\344\272\214\346\225\260\346\215\256\345\233\276\347\211\207.bmp" "b/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232\344\272\214\346\225\260\346\215\256\345\233\276\347\211\207.bmp" new file mode 100644 index 0000000000000000000000000000000000000000..dd34781ae345e0b7c5baa83472ee848095bbcf55 Binary files /dev/null and "b/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232\344\272\214\346\225\260\346\215\256\345\233\276\347\211\207.bmp" differ diff --git "a/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232\347\255\224\346\241\210.md" "b/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232\347\255\224\346\241\210.md" new file mode 100644 index 0000000000000000000000000000000000000000..92ccfe664447e5c714cbc2ab9659c539e678d001 --- /dev/null +++ "b/09 \346\241\202\346\263\275\347\205\234/\344\275\234\344\270\232\347\255\224\346\241\210.md" @@ -0,0 +1,562 @@ +```mysql +drop database users; +create database users charset=utf8; +use users; +create table Student( +Sno varchar(20) not null comment'学号', +Sname varchar(20) not null comment'学生姓名', +Ssex varchar(20) not null comment'学生性别', +primary key(Sno), +Sbirthday datetime comment'学生出生年月', +Class varchar(20) comment'学生所在班级' +) comment'学生表'; +create table Course( +Cno varchar(20) not null comment'课程号', +Cname varchar(20) not null comment'课程名称', +primary key(Cno), +Tno varchar(20) not null comment'教工编号' +) comment'课程表'; +create table Score( +Sno varchar(20) not null comment'学号', +Cno varchar(20) not null comment'课程号', +primary key(Sno,Cno), +Degree Decimal(4,1) comment'成绩' +) comment'成绩表'; +create table Teacher( +Tno varchar(20) not null comment'教工编号', +Tname varchar(20) not null comment'教工姓名', +Tsex varchar(20) not null comment'教工性别', +Tbirthday datetime comment'教工出生年月', +Prof varchar(20) comment'职称', +primary key(Tno), +Depart varchar(20) not null comment'教工所在部门' +) comment'教师表'; +alter table Course +add foreign key(Tno) references Teacher(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); +set @@foreign_key_checks=0; +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',76), +(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','助教','电子工程系'); +set @@foreign_key_checks=1; +-- 1,查询所有学生,都学了哪些课程,要显示学生信息和课程信息/ +select * from Student inner join Course; +-- 2,查询没有学生的教师的所有信息 +select Tname from Student inner join Teacher WHERE Sno having null; +4. 查询 +① 查询Score表中的最高分的学生学号和课程号。 +select Sno,Cno from Score where Degree =92 ; +select Sno,Cno from Score WHERE Degree <=> (Select MAX(Degree) from Score); +② 查询所有学生的Sname、Cno和Degree列。 +select Sname,Cno,Degree from Student cross join Score on Student.Sno = Score.Sno ; +③ 查询所有学生的Sno、Cname和Degree列。 +select Student.Sno,Cname,Degree from Student inner join Course cross join Score on Student.Sno = Score.Sno and Course.Cno = Score.Cno; +④ 查询所有学生的Sname、Cname和Degree列。 +select Sname,Cname,Degree from Student inner join Course cross join Score on Student.Sno = Score.Sno and Course.Cno = Score.Cno ; +⑤ 查询“95033”班学生的平均分。 +select AVG(Degree),Class from Student inner join Score on Student.Sno = Score.Sno where Class=95033; +⑥ 查询选修“3-105”课程的成绩高于“109”号同学成绩的所有同学的记录。 +select Sno from Score where Degree > 76; +select Sno from Score where Degree> (select Degree from Score where Cno = '3-105' and Sno = 109) ; +⑦ 查询score中选学多门课程的同学中分数为非最高分成绩的记录。 +select Degree from Score where Degree < (select MAX(Degree) from Score); +⑧ 查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。 +select * from Score where Degree >76; +select * from Score where Degree> (select Degree from Score where Cno = '3-105' and Sno = 109) ; +⑨ 查询和学号为108的同学同年出生的所有学生的Sno、Sname和Sbirthday列。 +select Sno,Sname,Sbirthday from Student where Sbirthday=1977; +select Sno,Sname,Sbirthday from Student group by Sbirthday having Sbirthday = Sno = 108 and Sbirthday ; +⑩ 查询“张旭“教师任课的学生成绩。 +select Degree from Teacher inner join Score where Tname='张旭'; +11 查询选修某课程的同学人数多于5人的教师姓名。 +select distinct Tname from Score inner join Teacher where Sno >5; +12 查询出“计算机系“教师所教课程的成绩表。 +select distinct Degree from Teacher inner join Score where Depart ='计算机系'; +13 查询“计算机系”与“电子工程系“不同职称的教师的Tname和Prof。 +select Tname,Prof from Teacher where Depart ='计算机系' or Depart ='电子工程系'; +14 查询选修编号为“3-105“课程且成绩至少高于选修编号为“3-245”的同学的Cno、Sno和Degree,并按Degree从高到低次序排序。 +select Cno,Sno,Degree from Score where Cno ='3-105' xor Degree > Cno ='3-245' xor Degree order by Degree desc ; +15 查询选修编号为“3-105”且成绩高于选修编号为“3-245”课程的同学的Cno、Sno和Degree. +select Cno,Sno,Degree from Score where Cno ='3-105' xor Degree > Cno ='3-245' xor Degree; +16 查询成绩比该课程平均成绩低的同学的成绩表。 +select Degree 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 inner join Course where Cname is null; +19 查询“男”教师及其所上的课程。 +select Tname,Tsex,Cname from Teacher inner join Course where Tsex ='男'; +20 查询最高分同学的Sno、Cno和Degree列。 +select Sno,Cno,Degree from Score where Degree =92; +select Sno,Cno,Degree from Score where Degree = (select MAX(Degree) from Score); +21 查询和“李军”同性别的所有同学的Sname. +select Sname from Student where Ssex ='男' and Sname != '李军'; +22 查询和“李军”同性别并同班的同学Sname. +select Sname from Student where Ssex ='男' and Sname != '李军' and Class ='95033'; +23 查询所有选修“计算机导论”课程的“男”同学的成绩表。 +select Degree from Course inner join Score cross join Student on Student.Sno = Score.Sno where Cname ='计算机导论' and Ssex ='男'; + +``` + +笔记 + +- **什么是分组查询?** + +> 将查询结果按照1个或多个字段进行分组,字段值相同的为一组 +> 其实就是按照某一列进行分类 + +- **分组使用** + +> **SELECT gender from employee GROUP BY gender;** +> +> 根据gender字段来分组,gender字段的全部值只有两个('男'和'女'),所以分为了两组 +> 当group by单独使用时,只显示出每一组的第一条记录 +> 所以group by单独使用时的实际意义不大 + +![img](https://pic3.zhimg.com/80/v2-2dd056cc432e89898c80cbacf78c3dda_720w.webp) + +对这个表进行GROUP BY操作 + +```text +SELECT * FROM employee; +``` + +![img](https://pic3.zhimg.com/80/v2-650d569e895acc26b20d0a0edc2596e6_720w.webp) + +只显示了每一组第一条记录 + +男生的第一个人是张三 女生的第一个人是王五 + +![img](https://pic2.zhimg.com/80/v2-a289b4d4803b3e9869656420f5c87d75_720w.webp) + +所以说GROUP BY 一般不单独使用 + + + +**一般来说 你按照什么分组 就查询什么东西** + +**比如:** + +```text +select department from employee group by department; +``` + +![img](https://pic2.zhimg.com/80/v2-9f78a7bd599627321b0323af525d6ff9_720w.webp) + +查询结果如上。 + +**分完组然后呢?** + +- **如何对分组后的结果进行查询?** + +**关键字:group_concat()** + +将职员表 按照部门分组 查询每个部门职员的姓名 + +```text +select department,group_concat(name) from employee group by department; +``` + +结果如下: + +![img](https://pic2.zhimg.com/80/v2-ae5227cf66ecdc638e79980dede53499_720w.webp) + +------ + +- **GROUP BY + 聚合函数** + +**for example:** + +将职员表 按照部门分组 查询每个部门职员的薪水 和 **薪水总数** + +```text +select department,group_concat(salary),sum(salary) from employee group by department; +``` + +![img](https://pic1.zhimg.com/80/v2-9b5ca13455b29ebcf2e598d38ea87754_720w.webp) + +> 查询每个部门的名称 以及 每个部门的人数 + +```mysql +select department,group_concat(name),count(*) from employee group by department; +``` + +> 查询每个部门的部门名称 以及 每个部门工资大于1500的人数 + +PS:**先把大于1500的人查出来 再做分组** + +```text +select department,group_concat(salary),count(*) from employee group by department; +``` + +------ + +**group by + having** + +- 用来分组**查询后**制定一些条件来输出查询结果 +- having的作用和where一样,但having只能用于group by +- 查询工资总和大于9000的部门名称以及工资和 + +```text +SELECT department,GROUP_CONCAT(salary),SUM(salary) FROM employee +GROUP BY department HAVING SUM(salary) > 9000; +``` + +- having和where的区别 + +> having是在分组后对数据进行过滤 +> where是在分组前对数据进行过滤 +> having后面可以使用分组函数(统计函数) +> where后面不可以使用分组函数 +> where是对分组前记录的条件,如果某行记录没有满足where子句的条件,那么这行记录不会参加分组;而having是对分组后数据的约束 + + + +- 查询工资和大于2000的 工资总和大于6000的部门名称以及工资和 + +```text +SELECT department,GROUP_CONCAT(salary).SUM(salary) FROM employee +WHERE salary > 2000 +GROUP BY department +HAVING SUNM(salary) > 9000 +ORDER BY SUM(salary) DESC; +//降序排列 +``` + +------ + +**书写顺序** + +![img](https://pic3.zhimg.com/80/v2-166d3cee10b01a68e90af2a5d5ed9866_720w.webp) + +------ + +**Limit的使用** + +![img](https://pic3.zhimg.com/80/v2-cc55920af6e230cfe251bf53dd35a9c6_720w.webp) + +```text +SELECT * FROM employee LIMIT 3,3; +``` + +**从第三行开始 取三条数据** + +**PS:行是从0开始数的** + +![img](https://pic3.zhimg.com/80/v2-320efb37091a14d6e9b35e997c81941a_720w.webp) + +![img](https://pic1.zhimg.com/80/v2-29ecf40b5281d6f98d6a78ecac889ab8_720w.webp) + +------ + +**limit可以用于分页操作** + +![img](https://pic3.zhimg.com/80/v2-71ce51c3e1d647067bc562f362b88ee6_720w.webp) + +- **什么是分组查询?** + +> 将查询结果按照1个或多个字段进行分组,字段值相同的为一组 +> 其实就是按照某一列进行分类 + +- **分组使用** + +> **SELECT gender from employee GROUP BY gender;** +> +> 根据gender字段来分组,gender字段的全部值只有两个('男'和'女'),所以分为了两组 +> 当group by单独使用时,只显示出每一组的第一条记录 +> 所以group by单独使用时的实际意义不大 + +![img](https://pic3.zhimg.com/80/v2-2dd056cc432e89898c80cbacf78c3dda_720w.webp) + +对这个表进行GROUP BY操作 + +```text +SELECT * FROM employee; +``` + +![img](https://pic3.zhimg.com/80/v2-650d569e895acc26b20d0a0edc2596e6_720w.webp) + +只显示了每一组第一条记录 + +男生的第一个人是张三 女生的第一个人是王五 + +![img](https://pic2.zhimg.com/80/v2-a289b4d4803b3e9869656420f5c87d75_720w.webp) + +所以说GROUP BY 一般不单独使用 + + + +**一般来说 你按照什么分组 就查询什么东西** + +**比如:** + +```text +select department from employee group by department; +``` + +![img](https://pic2.zhimg.com/80/v2-9f78a7bd599627321b0323af525d6ff9_720w.webp) + +查询结果如上。 + +**分完组然后呢?** + +- **如何对分组后的结果进行查询?** + +**关键字:group_concat()** + +将职员表 按照部门分组 查询每个部门职员的姓名 + +```text +select department,group_concat(name) from employee group by department; +``` + +结果如下: + +![img](https://pic2.zhimg.com/80/v2-ae5227cf66ecdc638e79980dede53499_720w.webp) + +------ + +- **GROUP BY + 聚合函数** + +**for example:** + +将职员表 按照部门分组 查询每个部门职员的薪水 和 **薪水总数** + +```text +select department,group_concat(salary),sum(salary) from employee group by department; +``` + +![img](https://pic1.zhimg.com/80/v2-9b5ca13455b29ebcf2e598d38ea87754_720w.webp) + +> 查询每个部门的名称 以及 每个部门的人数 + +```mysql +select department,group_concat(name),count(*) from employee group by department; +``` + +> 查询每个部门的部门名称 以及 每个部门工资大于1500的人数 + +PS:**先把大于1500的人查出来 再做分组** + +```text +select department,group_concat(salary),count(*) from employee group by department; +``` + +------ + +**group by + having** + +- 用来分组**查询后**制定一些条件来输出查询结果 +- having的作用和where一样,但having只能用于group by +- 查询工资总和大于9000的部门名称以及工资和 + +```text +SELECT department,GROUP_CONCAT(salary),SUM(salary) FROM employee +GROUP BY department HAVING SUM(salary) > 9000; +``` + +- having和where的区别 + +> having是在分组后对数据进行过滤 +> where是在分组前对数据进行过滤 +> having后面可以使用分组函数(统计函数) +> where后面不可以使用分组函数 +> where是对分组前记录的条件,如果某行记录没有满足where子句的条件,那么这行记录不会参加分组;而having是对分组后数据的约束 + + + +- 查询工资和大于2000的 工资总和大于6000的部门名称以及工资和 + +```text +SELECT department,GROUP_CONCAT(salary).SUM(salary) FROM employee +WHERE salary > 2000 +GROUP BY department +HAVING SUNM(salary) > 9000 +ORDER BY SUM(salary) DESC; +//降序排列 +``` + +------ + +**书写顺序** + +![img](https://pic3.zhimg.com/80/v2-166d3cee10b01a68e90af2a5d5ed9866_720w.webp) + +------ + +**Limit的使用** + +![img](https://pic3.zhimg.com/80/v2-cc55920af6e230cfe251bf53dd35a9c6_720w.webp) + +```text +SELECT * FROM employee LIMIT 3,3; +``` + +**从第三行开始 取三条数据** + +**PS:行是从0开始数的** + +![img](https://pic3.zhimg.com/80/v2-320efb37091a14d6e9b35e997c81941a_720w.webp) + +![img](https://pic1.zhimg.com/80/v2-29ecf40b5281d6f98d6a78ecac889ab8_720w.webp) + +------ + +**limit可以用于分页操作** + +![img](https://pic3.zhimg.com/80/v2-71ce51c3e1d647067bc562f362b88ee6_720w.webp) + +```mysql +inner join,full outer join,left join,right jion +内部连接 inner join 两表都满足的组合 +full outer 全连 两表相同的组合在一起,A表有,B表没有的数据(显示为null),同样B表有 +A表没有的显示为(null) +A表 left join B表 左连,以A表为基础,A表的全部数据,B表有的组合。没有的为null +A表 right join B表 右连,以B表为基础,B表的全部数据,A表的有的组合。没有的为null + + +查询分析器中执行: +--建表table1,table2: +create table table1(id int,name varchar(10)) +create table table2(id int,score int) +insert into table1 select 1,'lee' +insert into table1 select 2,'zhang' +insert into table1 select 4,'wang' +insert into table2 select 1,90 +insert into table2 select 2,100 +insert into table2 select 3,70 +如表 +------------------------------------------------- +table1|table2| +------------------------------------------------- +idname|idscore| +1lee|190| +2zhang|2100| +4wang|370| +------------------------------------------------- + +以下均在查询分析器中执行 + +一、外连接 +1.概念:包括左向外联接、右向外联接或完整外部联接 + +2.左连接:left join 或 left outer join +(1)左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值(null)。 +(2)sql语句 +select * from table1 left join table2 on table1.id=table2.id +-------------结果------------- +idnameidscore +------------------------------ +1lee190 +2zhang2100 +4wangNULLNULL +------------------------------ +注释:包含table1的所有子句,根据指定条件返回table2相应的字段,不符合的以null显示 + +3.右连接:right join 或 right outer join +(1)右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。 +(2)sql语句 +select * from table1 right join table2 on table1.id=table2.id +-------------结果------------- +idnameidscore +------------------------------ +1lee190 +2zhang2100 +NULLNULL370 +------------------------------ +注释:包含table2的所有子句,根据指定条件返回table1相应的字段,不符合的以null显示 + +4.完整外部联接:full join 或 full outer join +(1)完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。 +(2)sql语句 +select * from table1 full join table2 on table1.id=table2.id +-------------结果------------- +idnameidscore +------------------------------ +1lee190 +2zhang2100 +4wangNULLNULL +NULLNULL370 +------------------------------ +注释:返回左右连接的和(见上左、右连接) + +二、内连接 +1.概念:内联接是用比较运算符比较要联接列的值的联接 + +2.内连接:join 或 inner join + +3.sql语句 +select * from table1 join table2 on table1.id=table2.id +-------------结果------------- +idnameidscore +------------------------------ +1lee190 +2zhang2100 +------------------------------ +注释:只返回符合条件的table1和table2的列 + +4.等价(与下列执行效果相同) +A:select a.*,b.* from table1 a,table2 b where a.id=b.id +B:select * from table1 cross join table2 where table1.id=table2.id (注:cross join后加条件只能用where,不能用on) + +三、交叉连接(完全) + +1.概念:没有 WHERE 子句的交叉联接将产生联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1和table2交叉连接产生3*3=9条记录) + +2.交叉连接:cross join (不带条件where...) + +3.sql语句 +select * from table1 cross join table2 +-------------结果------------- +idnameidscore +------------------------------ +1lee190 +2zhang190 +4wang190 +1lee2100 +2zhang2100 +4wang2100 +1lee370 +2zhang370 +4wang370 +------------------------------ +注释:返回3*3=9条记录,即笛卡尔积 + +4.等价(与下列执行效果相同) +A:select * from table1,table2 +``` + + + + + diff --git "a/09 \346\241\202\346\263\275\347\205\234/\345\244\247\344\275\234\344\270\232.md" "b/09 \346\241\202\346\263\275\347\205\234/\345\244\247\344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..d464662b49b400a5011b13b4dce476324e5f3e7c --- /dev/null +++ "b/09 \346\241\202\346\263\275\347\205\234/\345\244\247\344\275\234\344\270\232.md" @@ -0,0 +1,287 @@ +# 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 | 母猪产后与护理师的二三事 | 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 | + +4. 作品类型(3分) + +| 类型编号 | 类型名称 | +| :------: | :------: | +| L01 | 玄幻 | +| L02 | 奇幻 | +| L03 | 武侠 | +| L04 | 仙侠 | +| L05 | 都市 | + + + +### 3、题目 + +> 所有题目要求使用SQL语句完成 + +1. 根据前面提供的表结构和表数据,创建数据库并分别创建这张四张表;并插入相关数据。(提醒:外键请注意建表顺序和插入数据的顺序) (30分) + + ```mysql + create database xiaoshuo charset=utf8; + use xiaoshuo; + create table author( + author_id int primary key comment'作家编号', + author_name varchar(20) not null unique comment'作家姓名', + credits int comment'积分', + vip_id varchar(20) not null comment'等级编号' + ) comment'作家信息表'; + create table vip( + vip_id varchar(20) primary key comment'等级编号', + vip_name varchar(20) not null unique + ) comment'作家等级信息表'; + create table story( + story_id int primary key comment'作品编号' auto_increment, + author_id int comment'作家编号', + type_id varchar(20) comment'类型编号', + story_name varchar(50) comment'作品名称', + views_number int comment'浏览量', + foreign key(author_id) references author(author_id) + ) comment'小说作品信息表'; + alter table author + add foreign key(vip_id) references vip(vip_id); + create table type( + type_id varchar(20) primary key comment'类型编号', + type_name varchar(20) not null unique + ) comment'小说作品类型表'; + alter table story + add foreign key(type_id) references type(type_id); + set @@foreign_key_checks=0; + 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','这只小龙虾不正经',8724), + (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分) + + ```mysql + alter table story modify story_name varchar(40); + ``` + +3. 在author表中增加一个性别字段 字段名:author_sex,类型: char(10),要求默认值为'男'。 (3分) + + ```mysql + alter table author add author_sex char(10) default'男'; + ``` + +4. 将作家编号为1005、1007的作家性别改为'女' 。(2分) + + ```mysql + update author set author_sex ='女' where author_id=1005; + update author set author_sex='女' where author_id=1007; + ``` + +5. 作家杜子腾,写了一篇名为《拜登夸我很帅》的都市小说,有854个浏览量,请将这条信息插入到story表。(3分) + + ```mysql + insert into story + values + (null,'1005',null,'拜登夸我很帅',854); + ``` + +6. 《拖拉机大战蜘蛛侠》这篇小说,浏览量涨了100,请更新story表中的相关数据。(2分) + + ```mysql + update story set views_number=563+100 where story_name='拖拉机大战蜘蛛侠'; + ``` + +7. 请删除story表的中《皇上滚开本宫只劫财》这篇小说相关数据。(2分) + + ```mysql + delete from story where story_name='皇上滚开本宫只劫财'; + ``` + +8. 查询 浏览量大于 8000的小说的作者编号和小说作品名称。(2分) + + ```mysql + select author_id,story_name from story where views_number>8000; + ``` + +9. 查询积分大于1000 并且会员等级高于vip03的作家所有信息。(3分) + + ```mysql + select * from author where credits >1000 and vip_id > 'vip03'; + ``` + +10. 查询姓名以杜字开头的作家的姓名,积分和等级编号。(3分) + + ```mysql + select author_name,credits,vip_id from author where author_name like'杜%'; + ``` + +11. 查询积分在100、1000之间的作家信息,以积分降序排列。 (3分) + + ```mysql + select * from author where credits between 100 and 1000 order by credits desc; + ``` + +12. 查询出小说的总浏览量,最高浏览量,最小浏览量,平均浏览量,给字段用上中文别名。(3分) + + ```mysql + select sum(views_number) 总流量 from story; + select max(views_number) 最高流量 from story; + select min(views_number) 最小流量 from story; + select avg(views_number 平均流量)from story; + ``` + +13. 查询各种等级的作家的平均积分和作家数量,并对查询结果使用中文别名。(3分) + + ```mysql + select avg(credits) 平均积分,sum(author_id)作家数量 from author; + ``` + +14. 查询小说数量大于等于2的分类编号和小说数量。(4分) + + ```mysql + select type_id,views_number from story where story_id >=2; + ``` + +15. 查询所有小说中浏览量最少的书的作品编号、作品名称和类型编号、浏览量。(4分) + + ```mysql + select author_id,story_name,type_id,views_number from story where views_number =(select min(views_number) from story); + ``` + +16. 查询积分比刘产高的作者所有信息。(5分) + + ```mysql + select * from author where credits >(select credits from author where author_name='刘产'); + ``` + +17. 查询出哪些白银作家是没有写小说的,显示这些作家的姓名、等级名称。(8分) + + ```mysql + select author_name,vip_id from author left join story on author.author_id=story.author_id where story_id is null ; + ``` + +18. 找出写过作品浏览量大于5000的作家的所有作品中浏览量不到1000的作品信息(8分) + + ```mysql + select * from story where views_number >5000 and views_number <1000; + ``` + +19. 查询所有小说的小说编号、小说名称、浏览量、分类名称、作者姓名、作者积分、作者等级名称,结果字段要用中文别名,并按浏览量降序排列,如果浏览量一样的,再按积分降序排列。(10分) + + ```mysql + select story_id 小说编号,story_name 小说名称,views_number 浏览量,type_id 分类名称,author.author_name 作者姓名,credits 作者积分,vip_id 作者等级名称 from story right join author on author.author_id=story.author_id order by views_number desc ,credits desc; + ``` + + diff --git "a/09 \346\241\202\346\263\275\347\205\234/\346\225\260\346\215\256\345\272\223\350\241\250\346\225\210\346\236\234\345\233\276.bmp" "b/09 \346\241\202\346\263\275\347\205\234/\346\225\260\346\215\256\345\272\223\350\241\250\346\225\210\346\236\234\345\233\276.bmp" new file mode 100644 index 0000000000000000000000000000000000000000..4787a8b557f6961b8835dabbdfd27ed08d2c3caa Binary files /dev/null and "b/09 \346\241\202\346\263\275\347\205\234/\346\225\260\346\215\256\345\272\223\350\241\250\346\225\210\346\236\234\345\233\276.bmp" differ