![0d8d9d90933e652d3a2650b5d39c90d8.png](https://i-blog.csdnimg.cn/blog_migrate/0c4ef63d98fcb4037d2312ed99251857.jpeg)
1. 表的加法 (union)
快速建立相同结构表(以course为例):
course ---》右键单击---》复制表---》结构和数据---》对新表重命名---》改数据
![77cf90a43fe63d16b9de9817fd2bbbe7.png](https://i-blog.csdnimg.cn/blog_migrate/b79dc43af0e7f27ae2bd03600ac96124.jpeg)
1)union不保留重复行
![3d332480beed12dd17b2c9ea9859ae3d.png](https://i-blog.csdnimg.cn/blog_migrate/1f2e02b2c17268c3110f3b5f06e71215.jpeg)
2)union all 保留重复行
![364079933d49511f664004422b0527be.png](https://i-blog.csdnimg.cn/blog_migrate/14932f15aac79e97451c9a692c4d91be.jpeg)
2. 表的联接
![ca2dd6ed2e9fa2c1cb1dd316384a3a89.png](https://i-blog.csdnimg.cn/blog_migrate/1a545211dbb8a97b15f595cc60a35750.jpeg)
1) 交叉联接(cross join):实际业务中应用比较少,但是其他联接的基础
![9c29fb18d644d9bda095856ae8261699.png](https://i-blog.csdnimg.cn/blog_migrate/176b956f91c5cf64131d58d6f7daa86c.png)
2) 内联接(inner join):交集
取数图例:
![52bee6bf83943cacaf2bac03a7539f20.png](https://i-blog.csdnimg.cn/blog_migrate/32a9779478cdd2af35859e40bd5c15aa.jpeg)
![dbfcc1eb53bebfd8c6487192bc18daeb.png](https://i-blog.csdnimg.cn/blog_migrate/37e5cf7701aaa0e6508b2a67fade34be.jpeg)
SQL语句:
select a.学号, a.姓名, b.课程号
from student as a inner join score as b
on a.学号 = b.学号;
![f138cfa9fb4dbcfe628ff5dec516b38d.png](https://i-blog.csdnimg.cn/blog_migrate/e20fd8170db555a4e4d886b66e602640.jpeg)
3) 左联接(left join)
取数图例:
![48db8ef5d2b415e770f6cae809637e2d.png](https://i-blog.csdnimg.cn/blog_migrate/2902894e1253ffacb0522c367280eba7.png)
![90c39df94cb72d15c695cce52681da1d.png](https://i-blog.csdnimg.cn/blog_migrate/96c84adee5055c1c2d08608d68848b2a.jpeg)
SQL语句:
select a.学号, a.姓名, b.课程号
from student as a left join score as b
on a.学号 = b.学号;
![19f6da2723d8525d7c99d625afb28179.png](https://i-blog.csdnimg.cn/blog_migrate/26afdc571b7c17a91c6fc46be2220e83.jpeg)
SQL语句:去掉交集部分
select a.学号, a.姓名, b.课程号
from student as a left join score as b
on a.学号 = b.学号
where b.学号 is Null;
![dd39c7e881068568cb9d5287306b1c11.png](https://i-blog.csdnimg.cn/blog_migrate/ca5a1cef704d68a5d4ee29701cd6d4b6.jpeg)
4) 右联接(right join)
取数图例:
![726529ec699d9664a38059723ab0ea57.png](https://i-blog.csdnimg.cn/blog_migrate/2c669b7510e84025d2112f750a32429c.jpeg)
![55d7f42755d7c1fc643accec72ffa375.png](https://i-blog.csdnimg.cn/blog_migrate/be30a4d9ac2e72d283107471d78f4d95.jpeg)
SQL语句:
select a.学号, a.姓名, b.课程号
from student as a right join score as b
on a.学号 = b.学号;
![db4103b4be28b88a3a79664b8d8c98d4.png](https://i-blog.csdnimg.cn/blog_migrate/c6ccbb9dff6d1fd17f39f9639a6362a0.jpeg)
SQL语句:去掉交集部分
select a.学号, a.姓名, b.课程号
from student as a right join score as b
on a.学号 = b.学号
where a.学号 is Null;
![4155cbf97bef13485edb6063a19ad870.png](https://i-blog.csdnimg.cn/blog_migrate/ff7e76217d8a0b34020c9f142128673f.jpeg)
5) 全联接(full join):MySQL不支持全连接
取数图例:
![a62e7f204156fd39e2d7a7c6fa4f59be.png](https://i-blog.csdnimg.cn/blog_migrate/8a5dbf8495cc2888d24f28721b0cd421.jpeg)
![d89b870adf0f349708b1dc21b9101a04.png](https://i-blog.csdnimg.cn/blog_migrate/bbdb6f5ae749ed267a730748ed89a353.jpeg)
联接总结图
![e79efd8335b94034840e9f679d7ecade.png](https://i-blog.csdnimg.cn/blog_migrate/2383edaad2df03ac1fd91f508a8af23c.jpeg)
3. 联接应用案例
问题1:查询所有学生的学号、姓名、选课数、总成绩
分析:
1)学号、姓名(student表)
2)选课数(每个学生的选课数、score表)
3)总成绩(每个学生的总成绩,score表,按学号分组,对成绩求和)
见图:
![098958000eac239c0cbef6a8ab8a6e3a.png](https://i-blog.csdnimg.cn/blog_migrate/e9ac82991e038fa3e84ef07b7a02214d.jpeg)
SQL语句
select a.学号, a.姓名, count(b.课程号) as 选课数, sum(b.成绩) as 总成绩
from student as a left join score as b
on a.学号 = b.学号
group by a.学号;
![a356e1545005d60b33bd9335b6ec5fdd.png](https://i-blog.csdnimg.cn/blog_migrate/ac8fd7d729bcabe39ab656ac2e506f4e.jpeg)
问题2:查询平均成绩大于85的所有学生的学号、姓名、平均成绩
分析:
1) 查询出所有学生的学号、姓名、平均成绩、学号、姓名(student表)
平均成绩(score表),按学号分组求平均成绩
2) 平均成绩 > 85
SQL语句
select a.学号, a.姓名, avg(b.成绩) as 平均成绩
from student as a left join score as b
on a.学号 = b.学号
where avg(b.成绩) > 85
group by a.学号
having avg(b.成绩) > 85;
![ede168aa33919022eb5ed3cec3e6b9e1.png](https://i-blog.csdnimg.cn/blog_migrate/3e23fcb852522cb516a99ce02d9917c0.jpeg)
问题3:查询学生的选课情况:学号、姓名、课程号、课程名称
分析:
1) 学号、姓名(student表)
课程号(score表)
2) 课程名称(course表)
SQL语句
select a.学号, a.姓名, b.课程号, c.课程名称
from student as a left inner join score as b
on a.学号 = b.学号
left inner join course as c
on b.课程号 = c.课程号;
![15d1d38769362eabcb201bfabd720b97.png](https://i-blog.csdnimg.cn/blog_migrate/3262212ac7c97dbf6bc677e9711b8218.jpeg)
4. case 表达式
case when (判断表达式) then (表达式)
when (判断表达式) then (表达式)
when (判断表达式) then (表达式)
…
else(表达式)
end
例1:
select 学号,课程号,成绩,
(case when 成绩 >= 60 then '及格'
when 成绩 < 60 then '不及格'
else
end) as 是否及格
from score;
![98192f52ffa3a7c2c7dce7990e862a99.png](https://i-blog.csdnimg.cn/blog_migrate/e5bbb8651ca6e012a20c7ea90c5e8a54.jpeg)
问题1:查询每门课程的及格人数和不及格人数
select 课程号,
sum(case when 成绩 >= 60 then 1
else 0
end) as 及格人数,
sum(case when 成绩 < 60 then 1
else 0
end) as 不及格人数,
from score
group by 课程号;
注:sum()不应写成sum ()
步骤见图:
![cb0a08c7f5aa2baa31be3effe7c6ab56.png](https://i-blog.csdnimg.cn/blog_migrate/ec115b40ac3e4a2ed6b8f7b970d2b93f.jpeg)
![06357395f397e4d7c9407d30c199ac81.png](https://i-blog.csdnimg.cn/blog_migrate/f567fac4b8754c96ac8b73cbd4588404.png)
注意事项:
1. else 子句可以默认不写,但是为了完整性,保留
2. end 不可省略不写
3. 该表达式可写在任何子句中
问题2:使用分段[100-85], [85-70], [70-60], [<60]来统计各科成绩,分别统计:各各分段人数、课程号和课程名称
select a.课程号,b.课程名称,
sum(case when 成绩 between 85 and 100 then 1
else 0
end) as '[100-85]',
sum(case when 成绩 >= 70 and 成绩 < 85 then 1
else 0
end) as '[85-70]',
sum(case when 成绩 >= 60 and 成绩 < 70 then 1
else 0
end) as '[70-60]',
sum(case when 成绩 < 60 then 1
else 0
end) as '[<60]'
from score as a right join course as b
on a.课程号 = b.课程号
group by a.课程号, b.课程名称; (这里加上课程名称对结果无影响)
![1ac71b239525c448de4551f26727d803.png](https://i-blog.csdnimg.cn/blog_migrate/97011e7da6be42504d73924a83cda133.jpeg)
SQLZOO练习
1.列出 賽事編號matchid 和球員名 player ,該球員代表德國隊Germany入球的。要找出德國隊球員,要檢查: teamid = 'GER'
select matchid, player
from goal
where teamid = 'GER';
![cb45e4c4e7823635c86454c262132cc7.png](https://i-blog.csdnimg.cn/blog_migrate/71a8ff1b70a486acc7f3ff77567a1531.jpeg)
2. 在表格 game中找出賽事1012的資料。只顯示賽事1012的 id, stadium, team1, team2
select game.id, game.stadium, game.team1, game.team2
from game left join goal
on game.id = goal.matchid
where game.id = '1012' and goal.matchid = '1012'
and goal.player = 'Lars Bender';
![52139ef65b4a266d613ee7654d98f738.png](https://i-blog.csdnimg.cn/blog_migrate/28189ce10802dee9dec8025365f9f68a.jpeg)
3.顯示每一個德國入球的球員名,隊伍名,場館和日期。
select goal.player, goal.teamid, game.stadium, game.mdate
from game inner join goal (之前用left join,但此处为两表共有的部分)
on game.id = goal.matchid
where goal.teamid = 'Gre';
![43ffd7e447640307526a3b4d261b6919.png](https://i-blog.csdnimg.cn/blog_migrate/8cd804ebfea5135db0fef4d328b6680a.jpeg)
以上结果与答案不符,可能数据有改变。
4. 列出球員名字叫Mario (player LIKE 'Mario%'
)有入球的 隊伍1 team1, 隊伍2 team2 和 球員名 player
select g1.team1, g1.team2, g2.player
from game as g1 right join goal as g2
on g1.id = g2.matchid
where g2.player like 'Mario%';
名字的模糊查询。
![bc540bcc3db7846f8bfebd8e4a61a493.png](https://i-blog.csdnimg.cn/blog_migrate/a7128464d6752a8e071c1eef56b17516.jpeg)
5. 列出每場球賽中首10分鐘gtime<=10
有入球的球員 player
, 隊伍teamid
, 教練coach
, 入球時間gtime
select g.player,g.teamid,e.coach,g.gtime
from goal as g left join eteam as e
on g.teamid = e.id
where g.gtime <= 10;
指定on的联接条件不能忘写,答案显示为错误,但是其给出的答案只是三次行改变了相对位置。
![c420098eca4d841f6a31ade7e1293b22.png](https://i-blog.csdnimg.cn/blog_migrate/32167c5874ceb680b67f5a45061bddc6.jpeg)
6. 列出'Fernando Santos'作為隊伍1 team1 的教練的賽事日期,和隊伍名。
select g.mdate, e.teamname
from game as g left join eteam as e
on e.id = g.team1
where e.coach = 'Fernando Santos';
![789bb380f1c9f0aa76efbbfa18d59854.png](https://i-blog.csdnimg.cn/blog_migrate/3eb83bd216d8cb211a16fc91008c112d.jpeg)
7. 列出場館 'National Stadium, Warsaw'的入球球員。
select g2.player
from game as g1 left join goal as g2
on g1.id = g2.matchid
where g1.stadium = 'National Stadium, Warsaw';
![185dca4e4de7419595511422657c9ceb.png](https://i-blog.csdnimg.cn/blog_migrate/c9f33797d64d78bf7c3f212069633201.png)
8. 以下例子找出德國-希臘Germany-Greece 的八強賽事的入球
修改它,只列出全部賽事,射入德國龍門的球員名字。
select player
from game as g1 inner join goal as g2
on g1.id = g2.matchid
where (g1.team1 = 'Ger' or g1.team2 = 'Ger')
and g2.player not in (select player
from goal
where teamid = 'Ger');
和给出的答案有出入,原因在于选取的名字应该用distinct
![0119967ff3fad67b033821647f6e2bd2.png](https://i-blog.csdnimg.cn/blog_migrate/677b54a17e96d5cadb6c00a894583aac.jpeg)
select distinct b.player
from game as a inner join goal as b on a.id = b.matchid
where (b.teamid = a.team1 and a.team2 = 'GER') or (b.teamid = a.team2 and a.team1 = 'GER');
以上语句可去重。
9.列出隊伍名稱teamname和該隊入球總數
select e.teamname, count(g.teamid)
from goal as g inner join eteam as e
on g.teamid = e.id
group by e.teamname;
![530310724dc868f5b9714bb7ba58847e.png](https://i-blog.csdnimg.cn/blog_migrate/7273aa8dcc5fb488d6ad5f5c9d7d7931.jpeg)
如果不用group by 分组,那么球队和进球数均为总数。
10. 列出場館名和在該場館的入球數字。
select g1.stadium, count(g2.matchid)
from game as g1 inner join goal as g2
on g1.id = g2.matchid
group by g1.stadium;
![ed093224af2b0ac742e9090407f041cc.png](https://i-blog.csdnimg.cn/blog_migrate/ca2d3071f0bffa875edd41ad5ba582f9.jpeg)
11. 每一場波蘭'POL'有參與的賽事中,列出賽事編號 matchid, 日期date 和入球數字。
select g2.matchid, g1.mdate, count(g2.matchid)
from game as g1 inner join goal as g2
on g1.id = g2.matchid
where g1.team1 = 'POL' or g1.team2 = 'POL'
group by g2.matchid;
![e248cf484087d6648900846cb35cd14d.png](https://i-blog.csdnimg.cn/blog_migrate/def895caa3527fdb2a0e72598252efe4.jpeg)
12. 每一場德國'GER'有參與的賽事中,列出賽事編號 matchid, 日期date 和德國的入球數字。
select g2.matchid, g1.mdate, count(g2.teamid = 'GER')
from game as g1 inner join goal as g2
on g1.id = g2.matchid
where (g1.team1 = 'GER' or g1.team2 = 'GER')
and g2.teamid = 'GER'
group by g2.matchid;
![d174a7e0c3193c5ef300d8eee32a0035.png](https://i-blog.csdnimg.cn/blog_migrate/82616262d03815a8b230bbc0e13d3b6e.jpeg)
13. 每场比赛主客队进球数。
select g1.mdate, g1.team1,
sum(case when g1.team1 = g2.teamid then 1
else 0
end ) as score1,
g1.team2,
sum(case when g1.team2 = g2.teamid then 1
else 0
end ) as score2
from game as g1 left join goal as g2
on g1.id = g2.matchid
group by g1.mdate,g1.id,g1.team1,g1.team2
order by g1.mdate,g1.id,g1.team1,g1.team2;
![3dc7c4edcc885d6a1d7a1f5ef85b3adb.png](https://i-blog.csdnimg.cn/blog_migrate/7a0fa419697b4465d64257e7423e6b31.jpeg)
此处自己问题在于,group by和order by 后之前没有添加g1.id,g1.team1,g1.team2;添加多个分组可避免同一天有多个比赛时,不知会只有一场比赛。