sql语句———多表联查

本文详细介绍了SQL中的四种查询方式:内连接、外连接(左外连接、右外连接)、自连接以及子查询。通过实例展示了如何查询员工与部门信息、查询特定条件的数据、以及进行复杂的数据聚合和筛选操作。同时,还涵盖了联合查询、表子查询等高级用法,帮助理解SQL在数据操作中的灵活性和实用性。
摘要由CSDN通过智能技术生成

连接查询

内连接:
相当于查询集合A与集合B的交集部分
外连接
左外连接:查询左表所有数据,以及两张表交集部分数据
右外连接:查询右表所有数据,以及两张表交集部分数据
自连接:当前表与自身的连接查询,自连接必须使用表别名
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

-- 内连接
-- 内连接演示
-- 1、查询每一个员工的姓名,以及关联的部门的名称(隐式内连接实现)
-- 表结构:emp,dept
-- 连接条件:emp.dept_id = dept.id
select emp.name, dept.name from emp, dept where emp.dept_id = dept.id;
select e.name, d.name from emp e, dept d where e.dept_id = d.id;
-- 2、查询每一个员工的姓名,以及关联的部门的名称(显式内连接实现)
-- 表结构:emp,dept
-- 连接条件:emp.dept_id = dept.id
-- 第一个表 inner join 第二个表 on 连接条件(inner关键字可以省略)
select e.name, d.name from emp e inner join dept d on e.dept_id = d.id;
-- 外连接
-- 外连接演示
-- 1、查询emp表的所有数据,和对应部门的信息(左外连接)(outer可省略掉)
-- 表结构:emp,dept
-- 连接条件:emp.dept_id = dept.id
select e.*, d.name from emp e left outer join dept d on e.dept_id = d.id;
-- 2、查询dept的所有数据,和对应的员工信息(右外连接)
select d.*, e.* from emp e right outer join dept d on e.dept_id = d.id;

select d.*, e.* from dept d left outer join emp e on e.dept_id = d.id;

-- 自连接
-- 1、查询员工以及所属领导的名字
-- 表结构:emp a, emp, b
select a.name, b.name from emp a, emp b where a.managerid = b.id;
-- 2、查询所有员工emp及其领导的名字emp,如果员工没有领导,也需要查询出来
-- 表结构:emp a, emp, b
select a.name '员工', b.name '领导' from emp a left join emp b on a.managerid = b.id;

-- 联合查询-union, union all
-- 对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。
-- 对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
-- union all会将全部的数据直接合并在一起,union会对合并之后的数据去重。
-- 1、将薪资低于5000的员工,和年龄大于50岁的员工全部查询出来。
select * from emp where salary < 5000
union all
select * from emp where age > 50;

-- 上述SQL语句执行以后会有重复的条目,执行下述语句可去重
select * from emp where salary < 5000
union
select * from emp where age > 50;

子查询

SQL语句中嵌套SELECT语句,称为嵌套查询,又称为子查询。
子查询外部的语句可以是INSERT/UPDATE/DELETE/SELECT的任何一个,根据子查询结果不同,分为:

标量子查询(子查询结果为单个值)
列子查询(子查询结果为一列)
行子查询(子查询结果为一行)
表子查询(子查询结果为多行多列)
-- 标量子查询
-- --------------------------------------------子查询---------------------------------------
-- 标量子查询
-- 1、查询销售部的所有员工信息
-- 先查询出销售部的部门ID
select id from dept where name = '销售部';
-- 根据销售部的部门ID查找员工信息
select * from emp where dept_id = 4;
select * from emp where dept_id = (select id from dept where name = '销售部');
-- 2、查询在东方白入职之后的员工信息
-- 查询方东白的入职日期
select entrydate from emp where name = '方东白';
-- 查询指定入职时期之后入职的员工信息
select * from emp where entrydate > '2009-02-12';
select * from emp where entrydate > (select entrydate from emp where name = '方东白');
-- 列子查询
-- 1、查询销售部和市场部的所有员工信息
-- 查询销售部和市场部的部门ID
select id from dept where name = '销售部' or name = '市场部';
-- 根据部门ID查询员工信息
select * from emp where dept_id in(2, 4);
select * from emp where dept_id in(select id from dept where name = '销售部' or name = '市场部');
-- 2、查询比财务部所有人工资都高的员工信息
-- 查询财务部所有人的工资
select id from dept where name = '财务部';
select salary from emp where dept_id = 3;
select salary from emp where dept_id = (select id from dept where name = '财务部');
-- 查询比财务部所有人工资都高的员工信息
select * from emp where salary > all (select salary from emp where dept_id = (select id from dept where name = '财务部'));
-- 3、查询比研发部其中任意一人工资高的员工信息
select id from dept where name = '研发部';
select salary from emp where dept_id = (select id from dept where name = '研发部');
select * from emp where salary > any (select salary from emp where dept_id = (select id from dept where name = '研发部'));
select * from emp where salary > some (select salary from emp where dept_id = (select id from dept where name = '研发部'));

-- 行子查询
-- 1、查询与张无忌的薪资及直属领导相同的员工信息
-- 查询张无忌的薪资及其直属领导
select salary, managerid from emp where name = '张无忌';
-- 查询与张无忌的薪资及直属领导相同的员工信息
select * from emp where salary = 12500 and managerid = 1;
select * from emp where (salary, managerid) = (12500, 1);
select * from emp where (salary, managerid) = (select salary, managerid from emp where name = '张无忌');

-- 表子查询
-- 子查询结果返回的是多行多列,这种查询称为表子查询
-- 1、查询与鹿杖客,宋远桥的职位和薪资相同的员工信息
-- 查询鹿杖客和宋远桥的职位和薪资
select job, salary from emp where name = '鹿杖客' or name = '宋远桥';
-- 查询与鹿杖客,宋远桥的职位和薪资相同的员工信息
select * from emp where (job, salary) in (select job, salary from emp where name = '鹿杖客' or name = '宋远桥');
-- 2、查询入职日期是2006-01-01之后的员工信息,及其部门信息
-- 查询入职日期是2006-01-01之后的员工信息
select * from emp where entrydate > '2006-01-01';
-- 查询这部分员工对应的部门信息
select e.*, d.* from (select * from emp where entrydate > '2006-01-01') e left join dept d on e.dept_id = d.id;

-- --------------------------------多表查询案例---------------------------------------------
create table salgrade(
    grade int,
    losal int,
    hisal int
) comment '薪资等级表';

insert into salgrade values (1, 0, 3000);
insert into salgrade values (2, 3001, 5000);
insert into salgrade values (3, 5001, 8000);
insert into salgrade values (4, 8001, 10000);
insert into salgrade values (5, 10001, 15000);
insert into salgrade values (6, 15001, 20000);
insert into salgrade values (7, 20001, 25000);
insert into salgrade values (8, 25001, 30000);

-- 1、查询员工的姓名、年龄、职位、部门信息(隐式内连接)
-- 表:emp,dept
-- 连接条件:emp.dept_id = dept.id
select e.name, e.age, e.job, d.name from emp e, dept d where e.dept_id = d.id;

-- 2、查询年龄小于30岁的员工的姓名、年龄、职位、部门信息(显式内连接)
-- 表:emp,dept
-- 连接条件:emp.dept_id = dept.id
select e.name, e.age, e.job, d.name from emp e inner join dept d on e.dept_id = d.id where e.age < 30;

-- 3、查询拥有员工的部门ID、部门名称
-- 表:emp,dept
-- 连接条件:emp.dept_id = dept.id
select distinct d.id, d.name from emp e, dept d where e.dept_id = d.id;

-- 4、查询所有年龄大于40岁的员工,及其归属的部门名称;如果员工没有分配部门,也需要展示出来
select e.*, d.name from emp e left join dept d on d.id = e.dept_id where e.age > 40;

-- 5、查询所有员工的工资等级
-- 表:emp,salgrade
-- 连接条件:emp.salary >= salgrade.losal and emp..salary <= salgrade.hisal
select e.*, s.grade, s.losal, s.hisal from emp e, salgrade s where e.salary >= s.losal and e.salary <= s.hisal;
select e.*, s.grade, s.losal, s.hisal from emp e, salgrade s where e.salary between s.losal and s.hisal;

-- 查询研发部所有员工的信息及工资等级
-- 表:emp,salarygrade, dept
-- 连接条件:e.salary between s.losal and s.hisal,emp.dept_id = dept.id
-- 查询条件: dept.name = '研发部'
select e.*, s.grade
from emp e,
     dept d,
     salgrade s
where e.dept_id = d.id
  and (e.salary between s.losal and hisal)
  and d.name = '研发部';

-- 7、查询研发部的平均工资
-- 表:emp,dept
-- 连接条件:emp.dept_id = dept.id
select avg(e.salary) from emp e, dept d where e.dept_id = d.id and d.name = '研发部';

-- 8、查询工资比灭绝高的员工信息
-- 查询灭绝的薪资
select salary from emp where name = '灭绝';
-- 查询工资比灭绝高的的员工信息
select * from emp where salary > (select salary from emp where name = '灭绝');

-- 9、查询比平均薪资高的员工信息
-- 查询员工的平均薪资
select avg(salary) from emp;
-- 查询比平均薪资高的员工信息
select * from emp where salary > (select avg(salary) from emp);

-- 10、查询低于本部门平均工资的员工信息
-- 比如查询指定部门平均薪资1
select avg(salary) from emp where emp.dept_id = 1;
-- 查询低于本部门平均工资的员工信息
select *, (select avg(salary) from emp e1 where e1.dept_id = e2.dept_id) '平均'
from emp e2
where e2.salary < (select avg(salary) from emp e1 where e1.dept_id = e2.dept_id);

-- 11、查询所有的部门信息,并统计部门的员工人数
select id,name from dept;
select id,name, (select count(*) from emp e where e.dept_id = d.id) '人数' from dept d;
select count(*) from emp where dept_id = 1;
-- 12、查询所有学生的选课情况,展示出学生名称,学号,课程名称
-- 表:student,course,student_course
-- 连接条件:student.id = student_course.studentid, course.id = student_course.courseid
select s.name, s.no, c.name
from student s,
     student_course sc,
     ccourse c
where s.id = sc.studentid
  and c.id = sc.courseid;

练习题:

create table course

(

  cno varchar2(10),

  cname varchar2(20),

  ccredit number(3)

)



insert all 

into course(cno,cname,ccredit) values('xd1','IS',3)

into course(cno,cname,ccredit) values('xd2','UI',6)

into course(cno,cname,ccredit) values('xd3','BI',9)

select * from dual;



select * from course;

drop table course;



create table student

(

  sno varchar2(10),

  sname varchar2(20),

  ssex char(2),

  sage int,

  sdept varchar2(20)

)



insert all 

into student(sno,sname,ssex,sage,sdept) values('200215125','王大锤','男',20,'IS')

into student(sno,sname,ssex,sage,sdept) values('200215126','刘循子墨','男',19,'UI')

into student(sno,sname,ssex,sage,sdept) values('200215127','孔连顺','男',21,'BI')

into student(sno,sname,ssex,sage,sdept) values('200215128','陈冬','女',18,'IS')

into student(sno,sname,ssex,sage,sdept) values('200215129','漩涡鸣人','男',32,'BI')

select * from dual;



select * from student;


drop table sc;
create table sc

(

  sno varchar2(10),

  cno varchar2(10),

  grade number(3)

)



insert all 

into sc(sno,cno,grade) values('200215125','xd1',65)

into sc(sno,cno,grade) values('200215125','xd2',70)

into sc(sno,cno,grade) values('200215125','xd3',90)

into sc(sno,cno,grade) values('200215126','xd1',85)

into sc(sno,cno,grade) values('200215126','xd2',45)

into sc(sno,cno,grade) values('200215126','xd3',75)

into sc(sno,cno,grade) values('200215127','xd1',85)

into sc(sno,cno,grade) values('200215127','xd2',100)

into sc(sno,cno,grade) values('200215127','xd3',58)

into sc(sno,cno,grade) values('200215128','xd1',69)

into sc(sno,cno,grade) values('200215128','xd2',78)

into sc(sno,cno,grade) values('200215128','xd3',89)

into sc(sno,cno,grade) values('200215129','xd1',58)

into sc(sno,cno,grade) values('200215129','xd2',86)

into sc(sno,cno,grade) values('200215129','xd3',98)

select * from dual;



select * from sc;

drop table sc



/*添加列*/

alter tabe student add sbirth date;

/*添加date类型的数据:to_date()*/

update student set sbirth= to_date('2021-03-05','yyyy-mm-dd');

/*删除列*/

alter table student drop column sbirth;

/*删除表中所有数据*/

delete from student;

/*修改表中某字段的数据类型*/

alter table student modify sname varchar2(30);





查询全体学生的信息

select * from student

select a.sno,sname,ssex,sage,sdept 

from student a;

查询全体学生的学号及姓名

select sno,aname from student;

查询成绩表中的学生学号,并使返回值中无重复值出现

select sno from sc;

select distinct sno from sc;

查询考试成绩有不及格的学生的学号

select * from sc where grade<60;

查询年龄不在20~23岁(包括20岁和23岁)之间的学生的姓名、系别和年龄

select sname,sdept,sage from student

where sage>=20 and sage<=23

select sname,sdept,sage from student

where sage between 20 and 23

select sname,sdept,sage from student

where sage in (20,21,22,23);

查询信息系(IS),数学系(MA)和计算机科学系(CS)学生的姓名和性别

select sname,ssex from student 

where sdept='IS'or sdept='MA' or sdept='CS'









1、在student表中增加一列出生日期(sbirth) ,并成功修改列中数据。

update student set sbirth= to_date('2021-04-05','yyyy-mm-dd');

2、删除student表中的出生日期列

alter table student drop column sbirth;

3、修改student表中系别列的数据类型

alter table student modify sname varchar2(30);

4、查询所有学生的信息

select * from student;

5、查询名字叫王大锤的学员信息

select * from student where sname='王大锤';

6、查询年龄为19岁的学员姓名、学号。

select sname,sno from student where sage=19;

7、查询不在IS专业的学员信息。

select * from student where sdept not in 'IS';

8、查询所有女学员的学号、姓名、专业。

select sno,sname,sdept from student where ssex='女';

9、查询所有不是IS和BI专业的学员信息。

select * from student where sdept not in ('IS','BI');

10、 查询所有10~ 20岁的学员姓名、年龄和专业。

select sname,sage,sdept from student where sage between 10 and 20;

11、查询所有不大于30岁的男演员的全部信息。

select * from student where sage<=30 and ssex='男';

12、查询所有专业。(去重)

select distinct sdept from student;









查询所有姓王学生的姓名、学号和性别

select sname,sno,ssex from student where sname like '王%';

select sname,sno,ssex from student where sname like '%大%';

mysql用法

select sname,sno,ssex from student where sname like '王_';

查所有有成绩的学生学号和课程号,并将学号按降序排序

select sno,cno from sc where grade is not null and order by sno desc;

查询课程号为xd1的学生平均成绩、学生总分及学生最高分数

select avg(grade) 平均成绩,sum(grade) as 学生总分,max(grade) 最高分数 from sc where cno='xd1';

查询有多少学生

select count(sno) from student;

查询选修了3门以上课程的学生学号

select sno,count(cno) from sc group by sno having count(cno)>=3;

查询每个学生选修的课程数量

select sno,count(cno) from sc group by sno;



1、查询专业里有S的学生信息。

select * from student where sdept like '%S';

2、查询名字里有'大'的学生信息。

select * from student where sname like '%大%';

3、查询并返回男学生的最大年龄。

select max(sage) from student where ssex='男';

4、查询并返回女学生的最小年龄。

select min(sage) from student where ssex='女';

5、查询并返回学生的平均年龄。

select avg(sage) from student;

6、查询并返回学生的年龄总和。

select sum(sage) from student;

7、查询并返回学生的专业的数量。

select count(sdept) from student;

8、查询各专业的学生的平均年龄。

select sdept,avg(sage) from student group by sdept;

9、查询男学生和女学生的数量。

select ssex,count(sno) from student group by ssex;

10、查询总人数大于3的性别及该性别的人数

select ssex,count(sno) from student group by ssex having count(sno)>=3;

11、查询人数大于2的专业

select sdept,count(sno) from student group by sdept having count(sno)>=2;

12、查询总年龄大于40的专业及该专业的总年龄

select sdept,sum(sage) from student group by sdept having sum(sage)>=40;

13、查询选修BI课程且成绩在90分以上的所有学生学号及姓名。

select student.sno,student.sname,student.sdept from student,sc 

where student.sdept='BI'and sc.grade>=90 and student.sno=sc.sno;

14、查询平均成绩超过70分的课程名

select course.cname from course,sc 

group by course.cname having avg(sc.grade)>=70;



查询每个学生的个人信息及考试成绩

select student.*,sc.* from student,sc where student.sno=sc.sno;

查询选修了IS是课程的学生的成绩

select sc.grade from course,sc where course.cno=sc.cno and cname='IS';

查询每个学生及其选修课程的所有信息

select student.*,course.cno,course.ccredit from student,course where student.sdept=course.cname;

查询平均年龄小于25的专业

select sdept,avg(sage) from student group by sdept having avg(sage)<25;


查询选修xd1课程且成绩在70分以上的所有学生学号和姓名
/*交叉连接*/
select student.sno,sname from student,sc where student.sno=sc.sno and cno='xd1' and grade>70
/*内连接:inner join*/
select student.sno,sname from student inner join sc on student.sno=sc.sno 
where cno='xd1' and grade>70;

查询平均成绩超过75分的课程名avg(grade) group by cname
/*交叉连接*/
select cname from course c,sc
where c.cno=sc.cno
group by cname
having avg(grade)>75
/*内连接*/
select cname 
from course c inner join sc on c.cno=sc.cno
where c.cno=sc.cno
group by cname
having avg(grade)>75

查询每个学生及选修课程的所有信息
select s.*,c.*,sc.* from student s,course c,sc
where s.sno=sc.sno
and c.cno=sc.cno

查询每个学生的学号,姓名及选修课程名
select s.sno,sname,cname from student s,course c,sc
where s.sno=sc.sno
and c.cno=sc.cno

/*外连接:左外连接,右外连接*/
select student.*,sc.*
from student left join sc on student.sno=sc.sno

select student.*,sc.*
from student right join sc on student.sno=sc.sno

1、查询每个学生及其选修课程的所有信息
select s.*,c.*,sc.* from student s,course c,sc
where s.sno=sc.sno
and c.cno=sc.cno
2, 查询王大锤的个人信息及分数
select student.*,sc.grade from student,sc
where student.sno=sc.sno
and sname='王大锤'
3、查询学生的学号、姓名、专业、课程号、分数以及学分
select student.sno,student.sname,student.sdept,course.cno,course.ccredit,sc.grade 
from student,course,sc
where student.sno=sc.sno
and course.cno=sc.cno
and student.sdept=course.cname
4、查询王大锤的学号、姓名及选修课程的分数
select student.sno,student.sname,sc.grade
from student,course,sc
where student.sno=sc.sno
and course.cno=sc.cno
and student.sdept=course.cname
and student.sname='王大锤'
5、查询没有个人信息的学生学号、课程号及分数(外连接)


6, 使用2()连接方式,将三张表连接起来


7、查询学生的学号及平均分数
select s.sno,avg(sc.grade) from student s,sc where s.sno=sc.sno group by s.sno;

8、查询学生的平均分大于75的学生姓名
select student.sname from student,sc 
group by sname having avg(grade)>75

9. 查询平均分大于80的课程名
select cname from course c,sc
where c.cno=sc.cno
group by cname
having avg(grade)>80
  • 16
    点赞
  • 116
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@Heartworm

你的鼓励就是我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值