diff --git "a/47 \346\235\216\345\277\265\345\277\265/20230325 \350\277\236\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240.md" "b/47 \346\235\216\345\277\265\345\277\265/20230325 \350\277\236\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..99118b24e594ce307d4e5c33ba4fa9560d6f4ad4 --- /dev/null +++ "b/47 \346\235\216\345\277\265\345\277\265/20230325 \350\277\236\350\241\250\346\237\245\350\257\242\347\273\203\344\271\240.md" @@ -0,0 +1,480 @@ +# 作业: + +~~~ mysql +# 1 创建数据库,并设置字符集 +create database adadad charset utf8; + +# 2 使用数据库 +use adadad; + +# 3 创建表结构 创建一个就插入一个表的数据 + +-- 创建价格表结构 +create table price +( + id int primary key auto_increment, -- 价格编号 + price double -- 水果价格 +); + +-- 插入价格数据 +insert into price +values (1, 2.30); +insert into price +values (2, 3.50); +insert into price +values (4, null); +insert into price +values (3, 5.5); + +-- 创建水果表结构 +create table fruit +( + id int primary key auto_increment, -- 水果编号 + name varchar(20) not null, -- 水果名称 + price_id int, -- 价格编号 + foreign key (price_id) references price (id) +); + +-- 插入水果的数据 +insert into fruit +values (1, '苹果', 1); +insert into fruit +values (2, '橘子', 2); +insert into fruit +values (3, '香蕉', null); + + + +-- 3.多表查询 +-- 3.1.笛卡尔积 +-- 需求:查询水果和价格信息 +select name, price +from fruit f + left join price p on f.price_id = p.id; + +-- 3.2.内连接 +-- 避免笛卡尔积问题怎么处理? +select * +from fruit f, + price p +where f.price_id = p.id; + + +-- 练习:查询苹果信息,显示苹果id和价格 +-- 分析:在水果表中可以查看苹果id 名字 ,在价格表中可以查看价格和价格id +select * +from fruit f, + price p +where f.price_id = p.id + and name = '苹果'; + + +-- 3.3左外连接 +-- 练习:查询所有水果信息和对应价格信息 +-- fruit f 位于left左边,称为左表,左外连接以左表为主 +-- price p 位于left右边,称为右表 +-- f.* :获取fruit水果表中的所有数据 +-- p.price : 获取price价格表的字段price的值 +select name, price +from fruit f + left join price p on f.price_id = p.id; + +-- 练习:查询没有写价格的水果及价格(先查询所有水果的价格信息,再筛选。) +select name, price +from fruit f + left join price p on f.price_id = p.id +where price is null; + + + +-- 3.4右外连接 +-- 练习:使用右外连接查询所有价格对应的水果名称和价格信息, +-- right join 表示右连接 +-- price p 称为右表 右外连接会查询右表即price表的全部数据以及和左表fruit f的交集 + + +-- 练习:查询出没有对应水果的价格编号和价格,水果名 +select price_id, price, name +from fruit f + left join price p on f.price_id = p.id; + +-- 练习:使用左外连接查询价格对应的水果,显示所有价格 +select name, price +from fruit f + left join price p on f.price_id = p.id; + +-- 4.子查询 + +-- 创建部门表 1 +CREATE TABLE dept +( + id INT PRIMARY KEY AUTO_INCREMENT, -- 部门编号 + NAME VARCHAR(20) -- 部门名称 +); + +INSERT INTO dept (NAME) +VALUES ('开发部'), + ('市场部'), + ('财务部'); + +-- 创建员工表 n +CREATE TABLE emp +( + id INT PRIMARY KEY AUTO_INCREMENT, + NAME VARCHAR(10), + gender CHAR(1), -- 性别 + salary DOUBLE, -- 工资 + join_date DATE, -- 入职日期 + dept_id INT, -- 部门编号 + foreign key (dept_id) references dept (id) +); + +INSERT INTO emp(NAME, gender, salary, join_date, dept_id) +VALUES ('孙悟空', '男', 7200, '2013-02-24', 1); +INSERT INTO emp(NAME, gender, salary, join_date, dept_id) +VALUES ('猪八戒', '男', 3600, '2010-12-02', 2); +INSERT INTO emp(NAME, gender, salary, join_date, dept_id) +VALUES ('唐僧', '男', 9000, '2008-08-08', 2); +INSERT INTO emp(NAME, gender, salary, join_date, dept_id) +VALUES ('白骨精', '女', 5000, '2015-10-07', 3); +INSERT INTO emp(NAME, gender, salary, join_date, dept_id) +VALUES ('蜘蛛精', '女', 4500, '2011-03-14', 1); + + +-- 1.查询工资最高的员工是谁 +-- 1.1 在emp员工表中查询最高工资 -- 9000 单行单列 +-- 1.2在emp员工表中根据上述查询的最高工资查询员工信息 +select name, salary +from emp +where salary = (select max(salary) from emp); +-- 2.查询工资小于平均工资的员工有哪些? +-- 2.1在emp员工表中查询平均工资 -- 单行单列 5860 +-- 2.2在emp员工表中查询小于上述的平均工资查询员工信息 +select * +from emp +where salary < (select avg(salary) from emp); +-- 3.查询工资大于5000的员工,来自于哪些部门,显示部门的名字 +-- 3.1 在员工表emp中查询工资大于5000的员工部门编号 -- 1 2 单列多值 作为子查询的条件使用in +-- 3.2在dept部门表中根据上述查询的部门编号查询部门名字 +select id, name +from dept +where id in (select dept_id from emp where salary > 5000); +-- 4. 查询开发部与财务部所有的员工信息 +-- 4.1 在dept表查询开发部和财务部的部门编号 -- 1 3 多行单列 作为子查询的条件使用in +-- 4.2在emp员工表中根据上述查询的部门编号查询员工信息 +select * +from emp +where dept_id in (select id from dept where name = '开发部' or name = '财务部'); + +-- 5.查询出2011年以后入职的员工信息,包括部门名称 +-- 5.1在emp表中查询2011年以后入职的员工信息 -- 多行多列,作为子查询一般使用as起别名作为临时表和其他表查询. +-- 5.2 将上述查询的结果作为临时表和dept表关联查询最后查询员工信息和部门名称 +select a.*, dept.NAME +from (select * from emp where join_date > '2011') a + inner join dept on dept_id = dept.id; + +-- 5.多表练习 子查询 +-- 教师表 +create table teacher +( + id int(11) primary key auto_increment, -- 教师编号 + name varchar(20) not null unique -- 教师姓名 +); + +-- 学生表 +create table student +( + id int(11) primary key auto_increment, -- 学生编号 + name varchar(20) NOT NULL unique, -- 学生姓名 + city varchar(40) NOT NULL, -- 学生城市 + age int -- 学生年龄 +); + +-- 课程信息表 +create table course +( + id int(11) primary key auto_increment, -- 课编号 + name varchar(20) not null unique, -- 课程名称 + teacher_id int(11) not null, -- 教师编号 + foreign key (teacher_id) references teacher (id) +); + +-- 学生选课表 +create table studentcourse +( + student_id int NOT NULL, -- 学生编号 + course_id int NOT NULL, -- 课程编号 + score double NOT NULL, -- 考试成绩 + foreign key (student_id) references student (id), + foreign key (course_id) references course (id) +); + +insert into teacher +values (null, '关羽'); +insert into teacher +values (null, '张飞'); +insert into teacher +values (null, '赵云'); + +insert into student +values (null, '小王', '北京', 20); +insert into student +values (null, '小李', '上海', 18); +insert into student +values (null, '小周', '北京', 22); +insert into student +values (null, '小刘', '北京', 21); +insert into student +values (null, '小张', '上海', 22); +insert into student +values (null, '小赵', '北京', 17); +insert into student +values (null, '小蒋', '上海', 23); +insert into student +values (null, '小韩', '北京', 25); +insert into student +values (null, '小魏', '上海', 18); +insert into student +values (null, '小明', '广州', 20); + +insert into course +values (null, '语文', 1); +insert into course +values (null, '数学', 1); +insert into course +values (null, '生物', 2); +insert into course +values (null, '化学', 2); +insert into course +values (null, '物理', 2); +insert into course +values (null, '英语', 3); + +insert into studentcourse +values (1, 1, 80); +insert into studentcourse +values (1, 2, 90); +insert into studentcourse +values (1, 3, 85); +insert into studentcourse +values (1, 4, 78); +insert into studentcourse +values (2, 2, 53); +insert into studentcourse +values (2, 3, 77); +insert into studentcourse +values (2, 5, 80); +insert into studentcourse +values (3, 1, 71); +insert into studentcourse +values (3, 2, 70); +insert into studentcourse +values (3, 4, 80); +insert into studentcourse +values (3, 5, 65); +insert into studentcourse +values (3, 6, 75); +insert into studentcourse +values (4, 2, 90); +insert into studentcourse +values (4, 3, 80); +insert into studentcourse +values (4, 4, 70); +insert into studentcourse +values (4, 6, 95); +insert into studentcourse +values (5, 1, 60); +insert into studentcourse +values (5, 2, 70); +insert into studentcourse +values (5, 5, 80); +insert into studentcourse +values (5, 6, 69); +insert into studentcourse +values (6, 1, 76); +insert into studentcourse +values (6, 2, 88); +insert into studentcourse +values (6, 3, 87); +insert into studentcourse +values (7, 4, 80); +insert into studentcourse +values (8, 2, 71); +insert into studentcourse +values (8, 3, 58); +insert into studentcourse +values (8, 5, 68); +insert into studentcourse +values (9, 2, 88); +insert into studentcourse +values (10, 1, 77); +insert into studentcourse +values (10, 2, 76); +insert into studentcourse +values (10, 3, 80); +insert into studentcourse +values (10, 4, 85); +insert into studentcourse +values (10, 5, 83); + + + +-- 1.查询获得最高分的学生信息。 +-- 1.1 在中间表中查询最高分-- 95 单行单列 +-- 1.2 在中间表中根据上述查询的最高分查询学生id +-- 1.3在学生表中根据上述查询的学生id查询学生信息 -- 一个班级最高分95,可以有多名学员,结果有可能是多行多列 +select * +from student +where id = (select student_id from studentcourse where score = (select max(score) from studentcourse)); + +-- 2.查询编号是2的课程比编号是1的课程最高成绩高的学生信息。 +-- 2.1在中间表查询课程编号是1的最高分数 -- 80 +-- 2.2在中间表中查询课程编号是2并且分数大于上述结果的学生编号 -- 多行单列 +-- 2.3 在学生表中根据上述查询的学生编号查询学生信息 +select * from student where id in +(select student_id from studentcourse where score> +(select max(score) from studentcourse where course_id=1) +and course_id=2); + +-- 3.查询编号是2的课程比编号是1的课程最高成绩高的学生姓名和成绩。 +-- 3.1在中间表查询课程编号是1的最高分数 -- 80 +-- 3.2在中间表中查询课程编号是2并且分数大于上述结果的学生编号和分数 -- 多行多列作为临时表 +-- 3.3 将上述查询的结果作为临时表 +select * from student where id in +(select student_id from studentcourse where score> +(select max(score) from studentcourse where course_id=1) +and course_id=2); + +-- 4.查询每个同学的学号、姓名、选课数、总成绩 +-- 4.1在中间表中根据学号分组查询学号 选课数 总成绩 -- 多行多列,作为临时表 +-- 4.2将上述查询的结果作为临时表和学生表进行关联查询 +select st.id,st.name,count(course_id),sum(score) from student st +inner join studentcourse s on st.id = s.student_id +group by st.id; +/* + 注意:如果子查询中查询的结果字段是聚合函数,并且最后结果需要使用聚合函数,那么必须使用as给聚合函数的字段起别名 + */ + + +-- 6.多表练习 连接查询 +-- 部门表 +CREATE TABLE dept +( + id INT PRIMARY KEY PRIMARY KEY, -- 部门id + dname VARCHAR(50), -- 部门名称 + loc VARCHAR(50) -- 部门位置 +); + +-- 添加4个部门 +INSERT INTO dept(id, dname, loc) +VALUES (10, '教研部', '北京'), + (20, '学工部', '上海'), + (30, '销售部', '广州'), + (40, '财务部', '深圳'); + +-- 职务表,职务名称,职务描述 +CREATE TABLE job +( + id INT PRIMARY KEY, -- 职务编号 + jname VARCHAR(20), -- 职务名称 + description VARCHAR(50) -- 职务简介 +); + +-- 添加4个职务 +INSERT INTO job (id, jname, description) +VALUES (1, '董事长', '管理整个公司,接单'), + (2, '经理', '管理部门员工'), + (3, '销售员', '向客人推销产品'), + (4, '文员', '使用办公软件'); + +-- 员工表 +CREATE TABLE emp +( + id INT PRIMARY KEY, -- 员工id + ename VARCHAR(50), -- 员工姓名 + job_id INT, -- 职务id + mgr INT, -- 上级领导 + joindate DATE, -- 入职日期 + salary DECIMAL(7, 2), -- 工资 + bonus DECIMAL(7, 2), -- 奖金 + dept_id INT, -- 所在部门编号 + CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id), + CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id) +); + +-- 添加员工 +INSERT INTO emp(id, ename, job_id, mgr, joindate, salary, bonus, dept_id) +VALUES (1001, '孙悟空', 4, 1004, '2000-12-17', '8000.00', NULL, 20), + (1002, '卢俊义', 3, 1006, '2001-02-20', '16000.00', '3000.00', 30), + (1003, '林冲', 3, 1006, '2001-02-22', '12500.00', '5000.00', 30), + (1004, '唐僧', 2, 1009, '2001-04-02', '29750.00', NULL, 20), + (1005, '李逵', 4, 1006, '2001-09-28', '12500.00', '14000.00', 30), + (1006, '宋江', 2, 1009, '2001-05-01', '28500.00', NULL, 30), + (1007, '刘备', 2, 1009, '2001-09-01', '24500.00', NULL, 10), + (1008, '猪八戒', 4, 1004, '2007-04-19', '30000.00', NULL, 20), + (1009, '罗贯中', 1, NULL, '2001-11-17', '50000.00', NULL, 10), + (1010, '吴用', 3, 1006, '2001-09-08', '15000.00', '0.00', 30), + (1011, '沙僧', 4, 1004, '2007-05-23', '11000.00', NULL, 20), + (1012, '李逵', 4, 1006, '2001-12-03', '9500.00', NULL, 30), + (1013, '小白龙', 4, 1004, '2001-12-03', '30000.00', NULL, 20), + (1014, '关羽', 4, 1007, '2002-01-23', '13000.00', NULL, 10); + +-- 工资等级表 +CREATE TABLE salarygrade +( + grade INT PRIMARY KEY, + losalary INT, -- 最低薪资 + hisalary INT -- 最高薪资 +); + +-- 添加5个工资等级 +INSERT INTO salarygrade(grade, losalary, hisalary) +VALUES (1, 7000, 12000), + (2, 12010, 14000), + (3, 14010, 20000), + (4, 20010, 30000), + (5, 30010, 99990); + +-- 1.查询所有员工信息。显示员工编号,员工姓名,工资,职务名称,职务描述。 +-- 1.1 确定几张表关联查询:2张表 emp job +-- 1.2 确定连接查询的条件即避免笛卡尔积的条件 emp.job_id = job.id +-- 1.3 确定要查询的结果字段:员工编号,员工姓名,工资,职务名称,职务描述 +select e.id,ename,salary,jname,description from emp e,job j +where e.job_id = j.id; + +-- 2.查询所有员工信息。显示员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置 +-- 2.1 确定几张表关联查询:3张表 emp job dept +-- 2.2 确定连接查询的条件即避免笛卡尔积的条件 emp.job_id = job.id and emp.dept_id=dept.id +-- 2.3 确定要查询的结果字段:员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置 +select e.id,ename,salary,jname,description,dname,loc +from emp e,job j,dept d +where e.job_id = j.id and e.dept_id = d.id; + +/* + 连接查询规律: + 1.确定几张表关联 + 2.确定连接查询的条件 + 3.确定要查询的结果字段 + 4.如果是n张表关联,那么避免笛卡尔积的条件的个数是:n-1 + */ + + +-- 3.查询所有员工信息。显示员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级。 +-- 1.确定几张表关联 4张表 emp job dept salarygrade +-- 2.确定连接查询的条件 :emp.job_id = job.id and emp.dept_id=dept.id +-- 其他条件:e.salary between salarygrade.losalary and salarygrade.hisalary +-- 3.确定要查询的结果字段 +select ename,salary,jname,description,dname,loc,grade from emp e,dept d,job j,salarygrade s +where e.job_id = j.id and e.dept_id=d.id and e.salary between s.losalary and s.hisalary; + +-- 4.查询出每个部门的部门编号、部门名称、部门位置、部门人数 +-- 4.1 在emp表中按照部门编号分组查询部门编号和每个部门人数 +-- 4.2 几张表关联:dept 上述临时表 +-- 4.3 条件 dept.id和临时表的dept_id相等 +-- 4.4 分析查询的结果部门编号、部门名称、部门位置、部门人数 +select d.id,dname,loc,count(ename) from dept d , emp e +where d.id = e.dept_id +group by d.id; + +~~~ +