cgb2110-day04

一,准备数据

–1,创建表

 
 
drop table if exists courses;
drop table if exists scores;
drop table if exists students;
drop table if exists teachers;
 
 
create table courses
(
cno varchar(5) not null,
cname varchar(10) not null,
tno varchar(3) not null,
primary key (cno)
);
 
 
create table scores
(
sno varchar(3) not null,
cno varchar(5) not null,
degree numeric(10,1) not null,
primary key (sno, cno)
);
 
 
create table students
(
sno varchar(3) not null,
sname varchar(4) not null,
ssex varchar(2) not null,
sbirthday datetime,
class varchar(5),
primary key (sno)
);
 
 
 
create table teachers
(
tno varchar(3) not null,
tname varchar(4),
tsex varchar(2),
tbirthday datetime,
prof varchar(6),
depart varchar(10),
primary key (tno)
);
 

–2,插入数据

INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (108 ,'曾华' ,'男' ,'1977-09-01',95033);
INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (105 ,'匡明' ,'男' ,'1975-10-02',95031);
INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (107 ,'王丽' ,'女' ,'1976-01-23',95033);
INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (101 ,'李军' ,'男' ,'1976-02-20',95033);
INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (109 ,'王芳' ,'女' ,'1975-02-10',95031);
INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (103 ,'陆君' ,'男' ,'1974-06-03',95031);
 
INSERT INTO TEACHERS(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (804,'易天','男','1958-12-02','副教授','计算机系');
INSERT INTO TEACHERS(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (856,'王旭','男','1969-03-12','讲师','电子工程系');
INSERT INTO TEACHERS(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (825,'李萍','女','1972-05-05','助教','计算机系');
INSERT INTO TEACHERS(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (831,'陈冰','女','1977-08-14','助教','电子工程系');
 
INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('3-105' ,'计算机导论',825);
INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('3-245' ,'操作系统' ,804);
INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('6-166' ,'模拟电路' ,856);
INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('6-106' ,'概率论' ,831);
INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('9-888' ,'高等数学' ,831);
 
INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (103,'3-245',86);
INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (105,'3-245',75);
INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (109,'3-245',68);
INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (103,'3-105',92);
INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (105,'3-105',88);
INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (109,'3-105',76);
INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (101,'3-105',64);
INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (107,'3-105',91);
INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (108,'3-105',78);
INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (101,'6-166',85);
INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (107,'6-106',79);
INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (108,'6-166',81);

二,多表联查

–1,概述

查询时,可能一张表无法满足查询需求,就需要联合多张表进行查询
方式1: 笛卡尔积
方式2: 连接查询–推荐!!!高效
方式3: 子查询

–2,笛卡尔积

#多表联查方式1:笛卡尔积
#练习1:查询部门表和员工表的所有数据
SELECT * FROM dept,emp
#添加查询条件,表明两张表的关系
SELECT * FROM dept,emp #逗号隔开表名
     #表名.字段名   表名.字段名
WHERE dept.deptno = emp.deptno
#练习2:查询课程表和老师表的所有数据
#select * from courses,teachers
SELECT courses.*,teachers.* FROM courses,teachers
WHERE courses.tno=teachers.tno
#练习3:查询在一区办公的员工名字
SELECT emp.ename FROM emp,dept 
WHERE emp.deptno=dept.deptno #描述两个表的关系
AND dept.loc='一区' #在一区办公
#练习4:查询在research部门工作的员工的信息
SELECT emp.*,COUNT(1) FROM emp,dept
WHERE emp.deptno=dept.deptno #描述两个表的关系
AND dept.dname='research' #在research部门的
GROUP BY emp.deptno#按照非聚合列分组,必须是合理的分组需求


–3,连接查询

#多表联查方式2:连接查询
#语法:多表之间用join连接,用on来描述两张表的关系,用where表示更多的条件
#练习1:查询在一区办公的员工名字
SELECT emp.ename FROM emp JOIN dept
ON emp.deptno=dept.deptno #描述两表的关系
WHERE dept.loc='一区' #在一区办公的
#练习2:查询员工表和部门表的所有数据
SELECT * FROM emp JOIN dept
ON emp.deptno=dept.deptno
#练习3:查询在research部门工作的员工的信息
SELECT emp.* FROM dept JOIN emp
ON dept.deptno=emp.deptno
WHERE dept.dname='research'#在research部门
#练习4:查询易天老师能讲的课程名称
SELECT courses.cname FROM teachers JOIN courses
ON teachers.tno=courses.tno #表关系
WHERE teachers.tname='易天' #易天老师
#练习5:查询学员李军的总得分
SELECT SUM(scores.degree) FROM students JOIN scores
ON students.sno = scores.sno
WHERE students.sname='李军'#学员李军

#连接查询:内连接,外连接
#内连接:inner join取交集,可以简写成join
#左外 连接:left join取左表的所有和右表满足的
#右外 连接:right join取右表的所有和左表满足的
#练习:查询部门表和员工表的所有数据
SELECT * FROM emp INNER JOIN dept
#内连接,取交集
ON dept.deptno=emp.deptno

#连接查询优化方案:小表驱动大表
SELECT * FROM dept LEFT JOIN emp
#左连接,取到左表的所有和右表满足条件的不满足用null填充
ON dept.deptno=emp.deptno

SELECT * FROM emp RIGHT JOIN dept
#右连接,取到右表的所有和左表满足条件的不满足用null填充
ON dept.deptno=emp.deptno

–4, 子查询

也叫嵌套查询,把上次的查询结果当做这次的查询条件在用

#多表联查方式3:子查询
#练习1:查询accounting部门的员工信息
#第一次查:根据部门名称查部门编号--查dept
SELECT deptno FROM dept WHERE dname='accounting'
#第二次查:根据部门编号查员工信息--查emp
SELECT * FROM emp WHERE deptno=1
#嵌套查询:
SELECT * FROM emp WHERE deptno=(
  SELECT deptno FROM dept WHERE dname='accounting'
)
#练习2:查询tony所在的部门名称
#2.2.拿着部门编号查部门名称
SELECT dname FROM dept WHERE deptno =(
  #2.1.拿着员工的名字查部门编号
  SELECT deptno FROM emp WHERE ename='tony'
)
#练习3:查询在二区办公的员工姓名
#第一次查:根据部门地址查部门编号
SELECT deptno FROM dept WHERE loc='二区'
#第二次查:根据部门编号查员工名字
#select ename from emp where deptno = 2,3 #语法不对
#SELECT ename FROM emp WHERE deptno in (2,3)#对,用in表示多个值
#嵌套查询:
SELECT ename FROM emp WHERE deptno IN(
 SELECT deptno FROM dept WHERE loc='二区'
)
#练习4:查询高于平均薪资的员工信息
SELECT * FROM emp WHERE sal>(
 SELECT AVG(sal) FROM emp 
)

三,扩展:索引

–1,概述

作用就是快速的查找数据
优点:查的快 缺点:本身索引是一张表需要空间存放,表越大查的越慢
使用: 如果经常按照指定字段来查询,这个字段添加索引.
分类:
1,单值索引: 给字段添加索引,并且这个索引只包含着 一个字段
2,复合索引: 给字段添加索引,并且这个索引只包含着 多个字段
3,唯一索引: 给字段添加索引,并且这个索引只包含着 一个字段,但是字段的值不能相同

–2,使用

#1,查询索引
#表里的主键数据库已经自己创建好了索引
SHOW INDEX FROM dept
SHOW INDEX FROM emp
#2,创建索引
#注意:不是所有字段都适合加索引,可以给经常查的字段加索引
#语法:create index 索引名 on 表名(字段名)
CREATE INDEX name_index ON dept(dname)
#3,使用索引
SELECT * FROM dept WHERE dname='research'
#4,查看SQL的执行计划/性能,观察查询结果里的key的值
EXPLAIN
SELECT * FROM dept WHERE dname='research'
#练习:创建,使用,查看 索引
CREATE INDEX ename_index ON emp(ename)
SHOW INDEX FROM emp
EXPLAIN SELECT * FROM emp WHERE ename='jack'

#创建唯一索引:要求字段的值必须唯一
#语法:create unique index 索引名 on 表名(字段名)
CREATE UNIQUE INDEX loc_index ON dept(loc)#失败的,loc的值重复啦
SHOW INDEX FROM dept
CREATE UNIQUE INDEX dname_index ON dept(dname)
#使用:dname字段拥有两种索引:唯一索引和单值索引,优先使用了唯一索引
EXPLAIN SELECT * FROM dept WHERE dname='research'

#创建复合索引:
#语法:create index 索引名 on 表名(字段名)
CREATE INDEX fuhe_index ON emp(job,deptno)
SHOW INDEX FROM emp
#!!!使用复合索引:遵循最左特性(必须包含着最左边的元素)
EXPLAIN SELECT * FROM emp WHERE job='员工' AND deptno=2#生效
EXPLAIN SELECT * FROM emp WHERE job='员工'#生效
EXPLAIN SELECT * FROM emp WHERE deptno=2 #失效!!!
EXPLAIN SELECT * FROM emp WHERE deptno=2 AND job='员工'#生效
EXPLAIN SELECT * FROM emp WHERE deptno=2 OR job='员工'#失效!!!

#删除索引
#语法:alter table 表名 drop index 索引名
ALTER TABLE emp DROP INDEX fuhe_index
SHOW INDEX FROM emp


四,作业

使用三种多表联查的方式完成以下练习:

练习1:查询research部门的所有员工姓名和工资
练习2:查询jack所在的部门信息
练习3:查询总监的部门信息
练习4:查询李军的平均分
练习5:查询陈冰能讲的课程名

猜你喜欢

转载自blog.csdn.net/u012932876/article/details/121601997