一、多表查詢
--編寫多表查詢語句的一般過程
--(1)、分析句子要涉及到哪些表
--(2)、對應的表中要查詢哪些關聯字段
--(3)、確定連接條件或篩選條件
--(4)、寫成完整的SQL查詢語句
1、多表查詢指使用SQL查詢時不只是一張表的查詢,要點:
① 多個表之間必須建立連接關系
② 表別名的用法
③ 如果from后面使用了表的別名 ,則select后和where后必須用別名代替
二、案例一
學生表student:
+-----+--------+-----+-------+------------+--------------+
| id? | name? | sex | birth | department | address? ? ? |
+-----+--------+-----+-------+------------+--------------+
| 901 | 張老大 | 男? |? 1985 | 計算機系? | 北京市海淀區 |
| 902 | 張老二 | 男? |? 1986 | 中文系? ? | 北京市昌平區 |
| 903 | 張三? | 女? |? 1990 | 中文系? ? | 湖南省永州市 |
| 904 | 李四? | 男? |? 1990 | 英語系? ? | 遼寧省阜新市 |
| 905 | 王五? | 女? |? 1991 | 英語系? ? | 福建省廈門市 |
| 906 | 王六? | 男? |? 1988 | 計算機系? | 湖南省衡陽市 |
+-----+--------+-----+-------+------------+--------------+
成績表score:
+----+--------+--------+-------+
| id | stu_id | c_name | grade |
+----+--------+--------+-------+
|? 1 |? ? 901 | 計算機 |? ? 98 |
|? 2 |? ? 901 | 英語? |? ? 80 |
|? 3 |? ? 902 | 計算機 |? ? 65 |
|? 4 |? ? 902 | 中文? |? ? 88 |
|? 5 |? ? 903 | 中文? |? ? 95 |
|? 6 |? ? 904 | 計算機 |? ? 70 |
|? 7 |? ? 904 | 英語? |? ? 92 |
|? 8 |? ? 905 | 英語? |? ? 94 |
|? 9 |? ? 906 | 計算機 |? ? 90 |
| 10 |? ? 906 | 英語? |? ? 85 |
+----+--------+--------+-------+
1、男同學的考試科目
select distinct(c_name) from score s1,student s2 where s2.id=s1.stu_id and sex='男‘;
select distinct(c_name) from score where stu_id in (select id from student where sex='男');
2、姓張同學的考試科目
select distinct(c_name) from score where stu_id in (select id from student where name like '張%');
select c_name from score,student where score.stu_id=student.id and name like '張%';
3、同時學習英語和計算機的學生信息
select * from student where id in (select stu_id from score where c_name='計算機'? and stu_id in (select stu_id from score where c_name='英語'));
select s1.* from student s1,score s2,score s3 where s1.id=s2.stu_id and s1.id=s3.stu_id and s2.c_name='計算機' and s3.c_name='英語';
練習:
1、女同學的考試科目
2、同時學習中文和計算機的學生信息;
3、姓王的同學并且有一科以上成績大于80分的學生信息;
4、查詢李四的考試科目(c_name)和考試成績(grade)
select c_name,grade from score,student where student.id=score.stu_id and name='李四';
5、查詢計算機成績低于95的學生信息
select student.* from score,student where student.id=score.stu_id and c_name='計算機' and grade<95;
6、查詢姓張或者姓王的同學的姓名、院系和考試科目及成績
select name,department,c_name,grade from student,score where student.id=score.stu_id and (name like '王%' or name like '張%' )
練習:
1、查詢都是湖南的學生的姓名、年齡、院系和考試科目及成績
2、成績大于80分的女同學的信息
3、查詢出女生成績最低的人的姓名;
案例二
如下,有三張表:
學生表student:
+-----+-------+-----+-----+
| SNO | SNAME | AGE | SEX |
+-----+-------+-----+-----+
|? 1 | 李強? |? 23 | 男? |
|? 2 | 劉麗? |? 22 | 女? |
|? 5 | 張友? |? 22 | 男? |
+-----+-------+-----+-----+
課程表course:
+-----+------------+---------+
| CNO | CNAME? ? ? | TEACHER |
+-----+------------+---------+
| k1? | c語言? ? ? | 王華? ? |
| k5? | 數據庫原理 | 程軍? ? |
| k8? | 編譯原理? | 程軍? ? |
+-----+------------+---------+
成績表sc:
+-----+-----+-------+
| SNO | CNO | SCORE |
+-----+-----+-------+
|? 1 | k1? |? ? 83 |
|? 2 | k1? |? ? 85 |
|? 5 | k1? |? ? 92 |
|? 2 | k5? |? ? 90 |
|? 5 | k5? |? ? 84 |
|? 5 | k8? |? ? 80 |
+-----+-----+-------+
1、檢索"李強"同學不學課程的課程號(CNO);
select cno from course where cno not in (select cno from
sc,student where sname='李強' andstudent.sno=sc.sno) ;
2、查詢“李強”同學所有課程的成績:
select score from student,sc where
student.sname='李強' and student.sno=sc.sno;
3、查詢課程名為“C語言”的平均成績
select avg(score) from sc,course where cname='c語言' and course.cno=sc.cno;
練習:
1、求選修K1 課程的學生的平均年齡;
select avg(age)from student,sc where student.sno=sc.sno and cno='k1';
2、求王老師所授課程的每門課程的學生平均成績。
select avg(score) from sc,course where teacherlike '王%' andcourse.cno=sc.cno group by sc.cno;
案例三
有四張表格:
學生表student:
+-----+-------+---------------------+------+
| sid | sname | sage? ? ? ? ? ? ? ? | ssex |
+-----+-------+---------------------+------+
| 01? | 趙雷? | 1990-01-01 00:00:00 | 男? |
| 02? | 錢電? | 1990-12-21 00:00:00 | 男? |
| 03? | 孫風? | 1990-05-06 00:00:00 | 男? |
| 04? | 李云? | 1990-08-06 00:00:00 | 男? |
| 05? | 周梅? | 1991-12-01 00:00:00 | 女? |
| 06? | 吳蘭? | 1992-03-01 00:00:00 | 女? |
| 07? | 鄭竹? | 1898-07-01 00:00:00 | 女? |
| 08? | 王菊? | 1990-01-20 00:00:00 | 女? |
+-----+-------+---------------------+------+
教室表teacher:
+-----+-------+
| tid | tname |
+-----+-------+
| 01? | 張三? |
| 02? | 李四? |
| 03? | 王五? |
| 04? | 趙六? |
+-----+-------+
課程表course:
+-----+-------+-----+
| cid | cname | tid |
+-----+-------+-----+
| 01? | 語文? | 02? |
| 02? | 數學? | 01? |
| 03? | 英語? | 03? |
| 04? | 物理? | 04? |
+-----+-------+-----+
成績表score:
+-----+-----+-------+
| sid | cid | score |
+-----+-----+-------+
| 01? | 01? |? ? 80 |
| 01? | 02? |? ? 90 |
| 01? | 03? |? ? 99 |
| 02? | 01? |? ? 70 |
| 02? | 02? |? ? 60 |
| 02? | 02? |? ? 80 |
| 03? | 01? |? ? 80 |
| 03? | 02? |? ? 80 |
| 03? | 03? |? ? 80 |
| 04? | 01? |? ? 50 |
| 04? | 02? |? ? 30 |
| 04? | 03? |? ? 20 |
| 05? | 01? |? ? 76 |
| 05? | 02? |? ? 87 |
| 06? | 01? |? ? 31 |
| 06? | 03? |? ? 34 |
| 07? | 02? |? ? 89 |
| 07? | 03? |? ? 98 |
+-----+-----+-------+
題目:
1、查詢"01"課程比"02"課程成績高的學生的信息及課程分數
1.1、查詢同時存在"01"課程和"02"課程的情況
select a.* , b.score,c.score from student a , score b , score c where a.sid = b.sid and a.sid = c.sid and b.cid = '01' and c.cid = '02' and b.score > c.score
1.2、查詢同時存在"01"課程和"02"課程的情況和存在"01"課程但可能不存在"02"課程 的情況(不存在時顯示為 null)
select a.* , b.score ,c.score from student a left join score b on a.sid = b.sid and b.cid = '01' left join score c on a.sid = c.sid and c.cid = '02' where b.score>IFNULL(c.score,0)
2、查詢"01"課程比"02"課程成績低的學生的信息及課程分數
3、查詢平均成績大于等于60分的同學的學生編號和學生姓名和平均成績
select a.sid , a.sname , cast(avg(b.score) as decimal(18,2)) avg_score from Student a , score b where a.sid = b.sid group by a.sid , a.sname having cast(avg(b.score) as decimal(18,2)) >= 60 order by a.sid
4、查詢平均成績小于60分的同學的學生編號和學生姓名和平均成績(注意成績為null的學生,使用ifnull()函數)
select a.sid , a.Sname , IFNULL(cast(avg(b.score) as decimal(18,2)),0) avg_score from Student a left join score b on a.sid = b.sid group by a.sid , a.sname having ifnull(cast(avg(b.score) as decimal(18,2)),0) < 60 order by a.Sid
5、查詢所有同學的學生編號、學生姓名、選課總數、所有課程的總成績
select a.sid AS 學生編號, a.Sname as 學生姓名, count(b.cid) 選課總數, sum(score) 所有課程的總成績 from Student a left join score b on a.sid = b.sid group by a.sid,a.Sname order by a.sid