SQL、关联查询

一,索引
–1,概述
为了提交数据的查询效率,可以给指定的列加索引
哪些列需要加索引?–常用来做查询条件的就加索引
分为几种:单值索引(一个索引只有一个列)
唯一索引(索引列的值必须唯一)
复合索引(一个索引可以包含多个列)
–2,常用SQL
–创建索引
create index 索引名 on 表名(列名)
–查看索引,主键会自动创建索引
SHOW INDEX FROM 表名
–删除索引
ALTER TABLE 表名 DROP INDEX 索引名
–练习:
#给teachers表的tname加索引,提高按照名字查询时的效率
#创建索引
create index tname_index on teachers(tname);
#查看索引
show index from teachers;
#删除索引
alter table teachers drop index tbirthday;
#添加唯一索引
desc teachers;
alter table teachers add UNIQUE(prof);#检查索引列的值必须唯一
#添加复合索引
alter table teachers add index many_index(tno,tname)

二,关联查询
–1,完成多表的关联查询,要知道查哪些表,表之间有什么关系
–2,练习
select * from dept;
select * from emp;
#笛卡尔积–是指多表联查,但是低效,因为查出来数据太多
select * from emp,dept;
#给笛卡尔积数据加过滤条件–就是指多表的关联关系
select * from emp,dept where emp.deptno = dept.deptno;#两张表的关系
select * from emp a,dept b where a.deptno = b.deptno;#使用别名
#查询students和scores表,其中sno=101的数据
select a.sno,a.sname,b.degree from students a,scores b
where a.sno=b.sno #两张表的关
and a.sno=101 #过滤条件

		#查询students和scores表 --inner join/left join/right join
		select * from scores a
		inner join scores b 
		on a.sno=b.sno #表间的关联关系
		where a.sno=101 #过滤结果

		#查询emp和dept表,过滤dname='research'的数据
		#笛卡儿积方式
		select * from dept,emp 
		where dept.deptno=emp.deptno#表间的关联关系
		and dept.dname='research';
		#关联查询方式
		select * from dept 
		inner join emp 
		on dept.deptno=emp.deptno#表间的关联关系
		where dept.dname='research'

		#子查询方式--把一次查询结果作为一张表来使用
		#查询research部门的员工信息
		#先查部门名称是research的部门编号
		select deptno from dept where dname='research'
		#再根据查到的部门编号查emp表
		#select * from emp where deptno=2
		select * from emp where deptno=(
				select deptno from dept where dname='research'
			)

		select * from students inner join 
		scores on  students.sno=scores.sno
		where  degree>90

		#练习子查询:#查询degree>90的学生信息
		#笛卡尔积方式
		select * from scores,students #表名
		where scores.sno=students.sno #两个表里的关联字段
		and scores.degree>90 #过滤条件
		#join方式
		select * from scores  #表名1
		inner join students  #表名2
		on  scores.sno=students.sno #两个表里的关联字段
		where scores.degree>90 #过滤条件
		#子查询方式
		select * from students #表名1
		where sno in(  #过滤条件
			select sno from scores where degree>90 #子查询
		)
		#练习子查询:#查询能讲高等数学的老师的信息
		select * from teachers where tno =(
			#先查courses表里老师的编号,再根据编号查teachers表
			select tno from courses where cname='高等数学'
		)
		select * from teachers a,courses b
		where a.tno=b.tno and b.cname='高等数学'

		#练习子查询:#查询部门地址在二区的员工信息
		select * from emp where deptno in(
				select deptno from dept where loc='二区'
		)

三,SQL练习题:
#查询所有记录
select * from teachers #低效
#只查询指定列
select tname,tsex from teachers #高效
#查询tno为804的记录
select * from teachers where tno=804
#模糊查询记录
select * from teachers where prof like ‘%教%’
#查询之间范围之间的所有记录
select * from teachers where tno BETWEEN 800 and 820
select * from teachers where tno>= 800 and tno<= 820
select * from teachers where tno in (804,820) #tno必须是804或者是820
# 查询满足两个条件的记录
select * from teachers where tsex=‘男’ and depart=‘计算机系’
select * from teachers where tsex=‘男’ or depart=‘计算机系’
#查询所有岗位
select distinct prof from teachers #distinct去掉重复值
#查询男老师的信息
select * from teachers where tsex=‘男’
#按tbirthday升序查询记录
select * from teachers order by tbirthday #默认是升序asc
#以tno升序、tbirthday降序查询记录
select * from teachers order by tno asc,tbirthday desc
# 查询总人数
select count(*) from teachers #低效
select count(1) from teachers #高效
# 查询各个系的人数
select depart,count(1) from teachers group by depart#非聚合列必须分组
# 查询至少有2人的岗位是啥
select prof,count(1) from teachers group by prof having count(1)>=2
# 查询记录中最年长和最年轻 #获取到出生日期数字越大年龄越小
select min(tbirthday),max(tbirthday) from teachers
# 查询大于平均年龄的记录
select * from teachers
#where里不能用聚合函数
where tbirthday < (
select avg(tbirthday) from teachers #子查询
)
#查询年龄最大的老师信息
select min(tbirthday) from teachers
#查询每个cno的最高分
select cno,max(degree) from scores group by cno
#查询每个cno的平均分
select * from scores group by cno
#查询cno='3-105’的课程信息
select * from courses where cno=‘3-105’
#查询scores表里出现过的课程信息
select * from courses where cno in (
select DISTINCT cno from scores
)
#查询没划分部门的员工信息
select * from emp where deptno is null
#查询同名的员工记录
#select * from emp where count(ename) > 1
select ename from emp GROUP BY ename having count(ename) > 1
#全部学生按出生日期排序
select * from students ORDER BY sbirthday #默认升序(年龄从大到小)
#每个班上最小年龄的学员
select class,max(sbirthday) from students GROUP BY class

	#查询学生的姓名和年龄
	select sname,year(now())-year(sbirthday) as age from students
	#查询男教师及其所上的课程
	select * from teachers a,courses b where a.tno=b.tno and a.tsex='男'

	#查询得分前3名的分数信息
	select * from scores order by degree desc limit 3

版权声明:本文为weixin_56747126原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。