连接查询
内连接
把两张表相同的地方查询出来
左连接
包括了内连接,同时还查询左表特有的内容
右连接
包括了内连接,同时还查询了右表独有的内容
内连接
语法:select * from 表1 inner join 表2 on 表1.字段 = 表2.字段
内连接最重要的是,找出两张表要关联的字段
显式内连接
查询a表和b表共有的数据
select * from a inner jion b on a.id = b.id;
查询students和scores共有的数据
select * from stundets inner join scores on students.studnetNo = scores.studentNo;
隐式内连接
语法:select * from 表1,表2 where 两个表的连接条件
select * from students,scores where students.studentNo = scores.studnetNo;
内连接查询显示指定的字段
students表与scores内连接,只显示姓名,课程号,成绩
select name,courseNo,score from studnets inner join scores students.studentNo = scores.studentNo;
表的别名在查询中的使用(当使用表别名可以缩短SQL语句)
select name,coursenNo,score from students st inner join scores cson st.studentsNo = sc.studnetNo;
查询成绩表信息,同时显示成绩对应的课程名称
select * from scores sc inner join course co on sc.courseNo = co.courseNo;
带有where条件的内连接
语法select * from 表1 inner join 表2 on 表1.字段 = 表2.字段 where条件
查询王昭君的信息,要求只显示姓名、课程号、成绩
select name,coursenNo,score from students st inner join scores sc on st.studentNo = sc.studentNo where name = '王昭君'
带有and逻辑运算符的内连接查询
查询姓名为王昭君,并且成绩小于90的信息,要求只显示姓名、成绩
select name,score from students st inner join scores sc on st.studentNo = sc.studentNo where st.name = '王昭君' and sc.score < 90;
多表内连接
查询学生信息和成绩以及成绩对应的课程名称(三张表关联)
select * from students inner join scores on students.studnetNo = scores.studentNo
inner join courses on scores.courseNo = courses.courseNo;
写SQL三步法
搭框架
基本的select语句框架搭建起来,如果有多表,把相应的多表也联合进来
看条件
决定where后面具体的条件
显示的字段
select后面到底要显示什么字段
查询所有学生的linux的课程成绩,要求只显示姓名、成绩、课程名
第一步:搭框架
select * from students inner join scores on students.studentNo = scores.studentNo inner join courses on scores.courseNo = courses.courseNo;
第二步:看条件
select * from students inner join scores on students.studentNo = scores.studentNo inner join courses on scores.courseNo = courses.courseNo where coursename = 'linux';
第三步:返回字段名
select name,score,coursename from students inner join scores on students.studentNo = scores.studentNo inner join courses on scores.courseNo = courses.courseNo where coursename = 'linux';
带有order by 排序的内连接查询
查询成绩最高的男生信息,要求显示姓名、课程名、成绩
select name,score,coursename from
students inner join scores on students.studentNo = scores.studentNo
inner join courses on scores.courseNo = courses.courseNo
order by score desc limit 0,1;
左连接
语法:select * from 表1 left join 表2 表1.字段=表2.字段
查询所有学生的信息以及成绩,包括没有成绩的学生
select * from students inner left join scores on studnets,studentNo = scores.studentNo;
右连接
语法:select * from 表1 right join 表2 表1.字段=表2.字段
查询所有的课程信息,包括没有成绩的课程
select * from student right join courses on scores.courseNo = courses.courseNo;
多表联合查询,同名字段的处理方式(如果多表查询出现重名字段时,一定要在所查字段前加上指定的表名)
如果一条select要用到多个表,表中有同名字段,就需要 表名.字段名 加以区分
select students.studentNo form students inner join scores on students.studentNo = scores.studentNo;
自关联
查询一共有多少省(因为省的没有上级,我们用NULL数据填充)
select count(*) from areas where is null;
查询一共有多少市
select count(*) from areas where is not null;
自关联是同一张表做连接查询
自关联下,一定找到同一张表可关联的不同字段
查询广东省所有城市 (当要用到自关联的时候,需要给表起别名)
select count(*) from areas a1 inner join areas a2 on a1.id = a2.pid where a1.name = '广东';
子查询
子查询是嵌套到主查询里面的
子查询作为主查询的数据源或者条件
子查询是独立可以单独运行的查询语句
主查询不能独立运行,依赖子查询的结果
查询大于平均年龄的学生记录
用子查询实现(子查询就是把一张表的结果作为另外一张表的条件)
select * from studnets where age > (select avg(age) from students);
标量子查询: 子查询返回结果只有一行,一列
查询30岁的学生的成绩
1.查询30岁学生的studentNo
select studentNo from students where age = 30;
select * from scores where studentNo in ('001','003','011');
用子查询实现
select * from scores where studentNo in (select * from scores where age = 30);
列子查询:子查询返回一列多行
用内连接实现
select * from student st inner join scores sc on st.studentNo = sc.studentNo where sex = '女';
用子查询实现
用子查询,查询所有女生的信息和成绩 (把表的查询结果作为另外一个表然后在做内连接)
select * from (select * from students where sex ='女') stu inner join scores sc on stu.studentsNo = sc.studentsNo;
表级子查询--子查询返回结果为多行,多列
练习
1.列出男职工的总数和女职工的总数
select sex,count(*) from employess group by sex;
2.列出非党员职工的总数
select count(*) from employess where politicalstatus ! = '党员';
3.列出所有职工工号,姓名以及所在部门的名称
select empid,empname,deptname from departments d inner join employees e on d.deptid = e.deptid;
4.列出所有职工工号,姓名和对应工资
select e.empid,empname,salary from employees e inner join salary on e.empid = s.empid;
5.列出领导岗的姓名以及所在部门名称
select empname,deptname from departments d inner join employees e on d.deptid = e.deptid where leader is null;
6.列出职工人数大于4的部门号和总人数
select deptid,count(*) from employees group by deptid having count(*) > 4;
7.列出职工总人数大于4的部门号和部门名称
select e.deptid,deptname count(*) from departments d inner join employees e on d.deptid = e.deptid group by e.deptid having count(*) > 4;
8.列出开发部和测试部的职工号,姓名
select empid,empname from departments d inner join employees e on d.deptid = e.deptid where deptname in ('测试部','开发部');
select e.empid,e.empname from (select * from departments where deptname in ('测试部','开发部')) d inner join employees e on d.depid = e.depid;
9.列出市场部所有女职工的姓名和政治面貌
select empname,politicalsta from departments d inner join employees e on d.deptid = e.deptid where deptname ='市场部' and sex ='女';
10.显示所有职工姓名和工资,包括没有工资的职工姓名
select empname,salary from employess e left join salary s on e.empid = s.empid;
11.求不姓孙的所有职工工资
select empname,sum(salary) from employees e left join salary s on e.empid = s.empid where empname not like '孙%';
select empname,salary from (select * from employess where not like '孙%') e inner join salary s on e.empid = s.empid;