数据库之多表查询

Posted maojiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库之多表查询相关的知识,希望对你有一定的参考价值。

 

一 ,多表查询

1、内连接:把两张表有对应关系的记录连接成一张虚拟表
select * from emp inner join dep on emp.dep_id = dep.id;

#应用:
    select * from emp,dep where emp.dep_id = dep.id and dep.name = "技术"; # 不要用where做连表的活

    select * from emp inner join dep on emp.dep_id = dep.id
        where dep.name = "技术"
    ;

2、左连接:在内连接的基础上,保留左边没有对应关系的记录
select * from emp left join dep on emp.dep_id = dep.id;


3、右连接:在内连接的基础上,保留右边没有对应关系的记录
select * from emp right join dep on emp.dep_id = dep.id;


4、全连接:在内连接的基础上,保留左、右边没有对应关系的记录
select * from emp left join dep on emp.dep_id = dep.id
union
select * from emp right join dep on emp.dep_id = dep.id;



#补充:多表连接可以不断地与虚拟表连接

查找各部门最高工资
select t1.* from emp as t1
inner join
(select post,max(salary) as ms from emp group by post) as t2
on t1.post = t2.post
where t1.salary = t2.ms

技术分享图片

技术分享图片

 

子查询:把一个查询语句用括号括起来,当做另一条查询语句的条件去用,称为子查询
 select emp.name from emp inner join dep on emp.dep_id=dep.id where dep.name=技术

 select name from emp where dep_id=
(select id from dep where name=技术);

查询平均年龄在25以上的部门
 select name from dep where id in
(select dep_id from emp group by dep_id having avg(age)>25)
 select dep.name from emp inner join dep on emp.dep_id=dep.id
   group by dep.name
   having avg(age)>25;
查看不足2个人的部门名(子查询得到的是有人的部门id)
 select * from emp where exists(select id from dep where id>3);
查询每一个部门最新入职的那个员工
 select t1.id,t1.name,t1.post,t1.hire_date,t2.post,t2.max_date from emp as t1 inner join (select post,max(hire_date) as max_date from emp group by post) as t2
 on t1.post=t2.post
 where t1.hire_date=t2.max_date
;

练习题

1 创建班级表:cid,caption
    学生表:sid,sname,gender,class_id
2 插入班级:
        1    linux一班
        2    linux二班
        3    linux三班
        4    linux四班
        5    python一班
        6    python二班
        7    python三班
        8    python四班
3 插入学生(都在linux2班):
            (王五, ),
            (王6蛋, ),
            (王7蛋, ),
            (王8, ) ;
4 插入学生:(都在linux3班):
                (刘五, ),
                (刘6, ),
                (刘7, ),
                (刘8, ) ;
5 插入学生:(都在python1班班):
                   (李1, ,
                (李2, ),
                (李3, ),
                (李4, ) ;
6 插入学生:(都在python2班班):
                (岳1, ),
                (岳2岳, ),
                (岳3岳, ),
                (岳4岳, ) ;
7 查询linux1班学生个数
8 查询linux2班学生个数
9  查询linux3班学生个数
10 查询linux1班 的班级id和所有人的名字,把名字列表的列名命名为names
11 查询python1班 班级id,学生id最大的人id,所有人的名字,把名字列表的列名命名为names
12 查询名字里有1的人的姓名,性别
13 查询名字叫王(某)某不定:如王4,王2,不包括王2蛋,人的姓名,性别
14 查询姓王的人的id,性别,姓名,班级id,只取第一条
15 查询所有学生,按学生id倒排序
16 查询所有学生,按学生姓名正排序
17 查询所有学生,按班级倒排序,sid正排序
18 查询姓王,名字只有俩字的人名和sid,按sid正序排列
19 查询姓王的人名和sid,按sid正序排列
20 查询名字以蛋结尾的人名和id,只取id最大的一条



INSERT INTO student (sname, gender, class_id)
VALUE
    (王五, , 2),
    (王6蛋, , 2),
    (王7蛋, , 2),
    (王8, , 2) ;


INSERT INTO student (sname, gender, class_id)
VALUE
    (刘五, , 3),
    (刘6, , 3),
    (刘7, , 3),
    (刘8, , 3) ;


INSERT INTO student (sname, gender, class_id)
VALUE
    (李1, , 5),
    (李2, , 5),
    (李3, , 5),
    (李4, , 5) ;


INSERT INTO student (sname, gender, class_id)
VALUE
    (岳1, , 6),
    (岳2岳, , 6),
    (岳3岳, , 6),
    (岳4岳, , 6) ;

-- 查询linux1班学生个数
SELECT count(*) from student GROUP BY class_id HAVING class_id=1;
SELECT count(*) from student where class_id=1


select count(*) from student where gender=;

--  查询linux1班 的班级id和所有人的名字,把名字列表的列名命名为names
SELECT class_id,GROUP_CONCAT(sname) as names from student GROUP BY class_id HAVING class_id=1;
-- 查询python1班 班级id,学生id最大的人id,所有人的名字,把名字列表的列名命名为names

SELECT class_id,max(sid),GROUP_CONCAT(sname) as names from student GROUP BY class_id HAVING class_id=5;

-- 查询名字里有1的人的姓名,性别
SELECT sname,gender from student where sname like %1%

-- 查询名字叫王(某)某不定:如王4,王2,不包括王2蛋,人的姓名,性别
SELECT sname,gender from student where sname like 王_
-- 查询姓王的人的id,性别,姓名,班级id,只取第一条
select * from student where sname like 王% LIMIT 1;
-- 查询所有学生,按学生id倒排序
SELECT* from student ORDER BY sid desc;
-- 查询所有学生,按学生姓名正排序
SELECT* from student ORDER BY sname asc;
-- 查询所有学生,按班级倒排序,sid正排序
SELECT  * from student ORDER BY class_id desc,sid asc;

-- 查询姓王,名字只有俩字的人名和sid,按sid正序排列
SELECT sname,sid from student where sname like 王_ ORDER BY sid 
-- 查询姓王的人名和sid,按sid正序排列
SELECT sname,sid from student where sname like 王% ORDER BY sid 

-- 查询名字以蛋结尾的人名和id,只取id最大的一条
SELECT sid,sname from student where sname like %蛋 ORDER BY sid desc limit 1;

练习

1、查询所有的课程的名称以及对应的任课老师姓名
select course.cname,teacher.tname from course INNER JOIN teacher on course.teacher_id=teacher.tid;
2、查询学生表中男女生各有多少人
select gender,count(sid) from student group by gender;
3、查询物理成绩等于100的学生的姓名
 
select student.sname from student WHERE sid IN
(select student_id from score INNER JOIN course on score.course_id=course.cid where course.cname=物理 and score.num=100);
4、查询平均成绩大于八十分的同学的姓名和平均成绩
select sname,avg(num) from student inner join score on student.sid = score.student_id 
group by student_id having avg(num)>80;

5、查询所有学生的学号,姓名,选课数,总成绩
select student.sid,sname,count(course_id),SUM(num) from student INNER JOIN score on student.sid=score.student_id GROUP BY student.sid;


6、 查询姓李老师的个数
select count(tid) from teacher where tname like 李%;
7、 查询没有报李平老师课的学生姓名
select sname from student where sid not in
(select student_id from score where course_id in(
select cid from course where teacher_id=(select tid from teacher where tname=李平老师)));

8、 查询物理课程比生物课程高的学生的学号
select t1.student_id  学号 from 
(select student_id ,num from score inner join course on score.course_id=course.cid  where cname=物理 )as t1
inner join 
(select student_id , num from score inner join course on score.course_id=course.cid  where cname = 生物) as t2
on t1.student_id = t2.student_id
where t1.num>t2.num;


9、 查询没有同时选修物理课程和体育课程的学生姓名
select sname from student inner join score on student.sid = score.student_id 46 join course on course.cid=score.course_id and cname in (物理,体育) 47 group by student_id having count(course_id)!=2;

10、查询挂科超过两门(包括两门)的学生姓名和班级
select sname 姓名,caption 班级 from student inner join score on student.sid = score.course_id
join class on class.cid = score.course_id
 where num<60 group by student_id having count(course_id)>=2;

11 、查询选修了所有课程的学生姓名
(select student_id,count(course_id) from score group by student_id having count(course_id) = (
select count(cid) from course)) as t1
on t1.student_id = student.sid;

12、查询李平老师教的课程的所有成绩记录
 
select num from score inner join course on course.cid=score.course_id
join teacher on teacher.tid=course.teacher_id
where tname = 李平老师;
13、查询全部学生都选修了的课程号和课程名
select cid,cname from course student;
14、查询每门课程被选修的次数
select course.cname,count(student_id) from score INNER JOIN course on score.course_id=course.cid
GROUP BY course_id;

15、查询之选修了一门课程的学生姓名和学号
select sname 姓名,student_id 学号 from student inner join score on student.sid = score.student_id
group by student_id having count(course_id)=1;

16、查询所有学生考出的成绩并按从高到低排序(成绩去重)
select DISTINCT num from score ORDER BY num desc;
17、查询平均成绩大于85的学生姓名和平均成绩
select sname 姓名,avg(num) 平均成绩 from student inner join score on student.sid = score.student_id
group by student_id having avg(num)>85;

18、查询生物成绩不及格的学生姓名和对应生物分数
select student.sname ,num 生物成绩 from student inner join score on student.sid = score.student_id
join course on course.cid=score.course_id
where cname=生物 and num<60;

19、查询在所有选修了李平老师课程的学生中,这些课程(李平老师的课程,不是所有课程)平均成绩最高的学生姓名
select sname from student where sid=(
select student_id from score where course_id in (
select cid from course where teacher_id=(select tid from teacher where tname=李平老师)
) group by student_id order by avg(num) desc limit 1
)

20、查询每门课程成绩最好的前两名学生姓名

文件

1、查询所有的课程的名称以及对应的任课老师姓名
select course.cname,teacher.tname from course INNER JOIN teacher on course.teacher_id=teacher.tid;
2、查询学生表中男女生各有多少人
select gender,count(sid) from student group by gender;
3、查询物理成绩等于100的学生的姓名
 
select student.sname from student WHERE sid IN
(select student_id from score INNER JOIN course on score.course_id=course.cid where course.cname=物理 and score.num=100);
4、查询平均成绩大于八十分的同学的姓名和平均成绩
select sname,avg(num) from student inner join score on student.sid = score.student_id 
group by student_id having avg(num)>80;

5、查询所有学生的学号,姓名,选课数,总成绩
select student.sid,sname,count(course_id),SUM(num) from student INNER JOIN score on student.sid=score.student_id GROUP BY student.sid;


6、 查询姓李老师的个数
select count(tid) from teacher where tname like 李%;
7、 查询没有报李平老师课的学生姓名
select sname from student where sid not in
(select student_id from score where course_id in(
select cid from course where teacher_id=(select tid from teacher where tname=李平老师)));

8、 查询物理课程比生物课程高的学生的学号
select t1.student_id  学号 from 
(select student_id ,num from score inner join course on score.course_id=course.cid  where cname=物理 )as t1
inner join 
(select student_id , num from score inner join course on score.course_id=course.cid  where cname = 生物) as t2
on t1.student_id = t2.student_id
where t1.num>t2.num;


9、 查询没有同时选修物理课程和体育课程的学生姓名
select sname from student inner join score on student.sid = score.student_id 46 join course on course.cid=score.course_id and cname in (物理,体育) 47 group by student_id having count(course_id)!=2;

10、查询挂科超过两门(包括两门)的学生姓名和班级
select sname 姓名,caption 班级 from student inner join score on student.sid = score.course_id
join class on class.cid = score.course_id
 where num<60 group by student_id having count(course_id)>=2;

11 、查询选修了所有课程的学生姓名
(select student_id,count(course_id) from score group by student_id having count(course_id) = (
select count(cid) from course)) as t1
on t1.student_id = student.sid;

12、查询李平老师教的课程的所有成绩记录
 
select num from score inner join course on course.cid=score.course_id
join teacher on teacher.tid=course.teacher_id
where tname = 李平老师;
13、查询全部学生都选修了的课程号和课程名
select cid,cname from course student;
14、查询每门课程被选修的次数
select course.cname,count(student_id) from score INNER JOIN course on score.course_id=course.cid
GROUP BY course_id;

15、查询之选修了一门课程的学生姓名和学号
select sname 姓名,student_id 学号 from student inner join score on student.sid = score.student_id
group by student_id having count(course_id)=1;

16、查询所有学生考出的成绩并按从高到低排序(成绩去重)
select DISTINCT num from score ORDER BY num desc;
17、查询平均成绩大于85的学生姓名和平均成绩
select sname 姓名,avg(num) 平均成绩 from student inner join score on student.sid = score.student_id
group by student_id having avg(num)>85;

18、查询生物成绩不及格的学生姓名和对应生物分数
select student.sname ,num 生物成绩 from student inner join score on student.sid = score.student_id
join course on course.cid=score.course_id
where cname=生物 and num<60;

19、查询在所有选修了李平老师课程的学生中,这些课程(李平老师的课程,不是所有课程)平均成绩最高的学生姓名
select sname from student where sid=(
select student_id from score where course_id in (
select cid from course where teacher_id=(select tid from teacher where tname=李平老师)
) group by student_id order by avg(num) desc limit 1
)

20、查询每门课程成绩最好的前两名学生姓名

 

以上是关于数据库之多表查询的主要内容,如果未能解决你的问题,请参考以下文章

mysql第四篇:数据操作之多表查询

MySQL之多表查询

46.数据库之多表查询

mysql数据操作之多表查询

数据库之多表查询

MySQL之多表查询