学习内容:

1.表的加法

2.表的联结

3.联结应用

4.case表达式

一、如何合并两个表?

01.使用union all 合并后,两组数据将全部合并(若有重复数据,不会自动合并)



select 课程号,课程名称
from course
union all
select 课程号,课程名称
from course1;





mysql取数据的交集 sql 取交集_mysql取数据的交集


02.若希望两个表合并且去重则直接使用 union 即可


select 课程号,课程名称
from course
union 
select 课程号,课程名称
from course1;


mysql取数据的交集 sql 取交集_用sql取a与b的交集_02


二、表的联结 (join)

1.交叉联结 cross join

枚举了所以排列方式,会合并所有合并项的列

2.内联结 (inner join)

只取 与之有关的表 取其交集


select a.学好,a.姓名,b.课程号
from student as a inner join score as b
on a.学号=b.学号;


3.左联结 (left join)

取左边的表的数据 与 交集部分


select a.学号,a.姓名,b.课程号
from student as a left join score as b
on a.学号=b.学号


如果你只想取 左边表的数据, 去掉关联部分 可将右侧表数据标识 为 Null


select a.学号,a.姓名,b.课程号
from student as a left join score as b
on a.学号=b.学号
where b.学号=Null;


4.右联结 (right join)

取右边的表的数据 与 交集部分


select a.学号,a.姓名,b.课程号
from student as a right join score as b
on a.学号=b.学号


如果你只想取 右边表的数据, 去掉关联部分 可将右侧表数据标识 为 Null


select a.学号,a.姓名,b.课程号
from student as a right join score as b
on a.学号=b.学号
where a.学号=Null;


5.全联结(full join)

关联全部数据

三、重温sql运行顺序

select 查询结果 --第二步

from 从那张表中查询数据 (关联) --第一步

where 查询条件 (运算符,模糊查询)

group by 分组

having 对分组结果指定条件

order by 对查询结果排序 --第三步

limit 从查询结果取出指定行

四、联结应用案例

练习1:查询所有学生的学号,姓名,选课数,总成绩


select -- 查询结果是 学生学号,姓名,选课数需要汇总, 以及总成绩
from 需要关联[student]与[score]两个表
where --无条件查询
group by --需要按学号区分学生
having --无对分组结果指定条件 
order by --无排序
limit --无从查询结果取出指定行


编写如下:


select a.学号,a.姓名,count(b.课程号)as'选课数',sum(b.成绩)as'总成绩'
from student as a left join score as b
on a.学号=b.学号
GROUP BY a.学号;


mysql取数据的交集 sql 取交集_用sql取a与b的交集_03


练习2:查询平均成绩大于85分的所有学生的学号,姓名 和 平均成绩


select -- 查询结果是 学生学号,姓名,计算平均成绩
from 需要关联[student]与[score]两个表
where --无条件查询
group by --按学生学号分组
having --平均分大于85分 
order by --无排序
limit --无从查询结果取出指定行


编写如下:


select a.学号 , a.姓名 , avg(b.成绩)as'平均成绩'
from student as a left join score as b
on a.学号=b.学号
group by a.学号
having avg(b.成绩)>85;


mysql取数据的交集 sql 取交集_sql_04


练习3: 查询学生的选课情况:学号,姓名,课程号,课程名称


select -- 查询结果是 学生学号,姓名,课程号 和 课程名称
from 需要关联3各表[student]与[score]与[course]两个表
where --无条件查询
group by --无
having --无
order by --无排序
limit --无从查询结果取出指定行


编写如下:


select a.学号 , a.姓名 , b.课程号 , c.课程名称
from student as a inner join score as b inner join course as c;


mysql取数据的交集 sql 取交集_数据_05


五、case表达式

表达方式: sum(case when <判断表达式> then <表达式>

....

else <表达式>

end) as '表名字'

练习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 课程号;


mysql取数据的交集 sql 取交集_条件查询_06


练习2:使用分段【100~85】,【85~70】,【70~60】,【<60】来统计各科成绩,分别统计各分数分段人数: 课程ID和课程名称


select a.学号,b.课程名称,
sum(case when 成绩 >= 85  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.课程名称;


六、sql zoo

https://sqlzoo.net/wiki/The_JOIN_operation/zhsqlzoo.net


1.修改此SQL以列出 賽事編號matchid 和球員名 player ,該球員代表德國隊Germany入球的。要找出德國隊球員,要檢查: teamid = 'GER'


SELECT matchid, player
FROM goal 
WHERE teamid = 'GER'


2.留意在 goal 表格中的欄位 matchid ,是對應表格game的欄位id。我們可以在表格 game中找出賽事1012的資料。

只顯示賽事1012的 id, stadium, team1, team2


SELECT id,stadium,team1,team2
  FROM game
where id= 1012;


3.我們可以利用JOIN來同時進行以上兩個步驟。


SELECT *
  FROM game JOIN goal ON (id=matchid)


語句FROM 表示合拼兩個表格game 和 goal的數據。語句 ON 表示如何找出 game中每一列應該配對goal中的哪一列 -- goalid 必須配對gamematchid 。 簡單來說,就是ON (game.id=goal.matchid)

以下SQL列出每個入球的球員(來自goal表格)和場館名(來自game表格)

修改它來顯示每一個德國入球的球員名,隊伍名,場館和日期。


select a.player, a.teamid, b.stadium, b.mdate
from goal as a inner join game as b 
on b.id = a.matchid
where teamid = 'GER';


4.使用上題相同的 JOIN語句,

列出球員名字叫Mario (player LIKE 'Mario%')有入球的 隊伍1 team1, 隊伍2 team2 和 球員名 player


select b. team1,b. team2,a. player
from goal as a inner join game as b
on b.id=a.matchid
where a. player like 'Mario%';


5.表格eteam 貯存了每一國家隊的資料,包括教練。你可以使用語句 goal JOIN eteam on teamid=id來合拼 JOIN 表格goal 到 表格eteam

列出每場球賽中首10分鐘gtime<=10有入球的球員 player, 隊伍teamid, 教練coach, 入球時間gtime


SELECT a.player, a.teamid, b.coach, a.gtime
FROM goal as a inner join eteam as b
on a. teamid =b. id
 WHERE gtime<=10  ;


6.列出'Fernando Santos'作為隊伍1 team1 的教練的賽事日期,和隊伍名。


select a.mdate,b.teamname
from game as a inner join eteam as b
on a.team1 = b.id
where b. coach='Fernando Santos';


7.列出場館 'National Stadium, Warsaw'的入球球員。


select b.player
from game as a inner join goal as b
on a.id = b.matchid
where a. stadium =   'National Stadium, Warsaw';


8.以下例子找出德國-希臘Germany-Greece 的八強賽事的入球

修改它,只列出全部賽事,射入德國龍門的球員名字。


SELECT distinct player
  FROM game JOIN goal ON matchid = id 
    WHERE (teamid=team1 and team2='GER')or( teamid=team2 and team1='GER');


9.列出隊伍名稱 teamname 和該隊入球總數


SELECT teamname, count(teamname)
  FROM eteam inner JOIN  goal ON id=teamid
 group BY teamname;


10.列出場館名和在該場館的入球數字。


SELECT stadium, count(stadium)as'入球數'
  FROM game inner JOIN  goal ON id=matchid
 group BY stadium;


11.每一場波蘭'POL'有參與的賽事中,列出賽事編號 matchid, 日期date 和入球數字。


SELECT matchid, mdate, count(matchid)as'入球數'
  FROM game JOIN goal ON matchid = id 
 WHERE (team1 = 'POL' OR team2 = 'POL')
group by matchid;


12.每一場德國'GER'有參與的賽事中,列出賽事編號 matchid, 日期date 和德國的入球數字。


select matchid, mdate,count(player)as'入球數'
from game join goal on matchid=id
where  teamid = 'GER' 
group by matchid;


13.查找出所有比赛的日期,每场比赛中对战双方各自进球数


select mdate,team1,
sum(case when team1=teamid then 1 else 0 end )as 'score1',
team2,
sum(case when team2=teamid then 1 else 0 end )as 'score2' 
from game left join goal on matchid = id 
group by id,mdate,team1,team2
order by mdate , id,team1,team2;