![47b8960fc5d75eb7ce8da20ffa72b4d3.png](https://img-blog.csdnimg.cn/img_convert/47b8960fc5d75eb7ce8da20ffa72b4d3.png)
![6f782e4e35267decdf2844b4e4710c0c.png](https://img-blog.csdnimg.cn/img_convert/6f782e4e35267decdf2844b4e4710c0c.png)
1. 组合查询 UNION
UNION 联合,将多条查询语句的结果合并成一个结果,可以理解为是将多表结果加在一起。
- 语法:
查询语句1
UNION/UNION ALL
查询语句2
...
- 应用场景:
要查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致时。
- 特点:
- 要求多条查询语句的查询列数保持一致;
- 要求多条查询语句查询的每一列的类型和顺序最好一致(不一致也不会报错,但内容就乱了);
- union 关键字默认去重,如果使用union all可以包含重复项。
![c0437a7c240e604087080b4e15691e29.png](https://img-blog.csdnimg.cn/img_convert/c0437a7c240e604087080b4e15691e29.png)
2. 多表联结 JOIN
联结是指,将多个存在相关关系的数据表,通过指定的条件(字段之间的比较运算),联结成一个数据表的过程。
【分类】
- CROSS JOIN --交叉联结
- INNER JOIN --内联结
- LEFT JOIN --左联结
- RIGHT JOIN --右联结
- FULL JOIN --全联结
![a8a287adaaa1cf442dd1d8bd4e487602.png](https://img-blog.csdnimg.cn/img_convert/a8a287adaaa1cf442dd1d8bd4e487602.png)
注意:多表联结,每个表名建议起别名。
2.1 交叉联结 CROSS JOIN
又称笛卡尔积,是将每个表的所有行都联结在一起,联结表的行数=表1的行数 * 表2的行数。
为了便于理解,我列出2个简单数据表来表示联结关系。
![407d7e482c11c2474c34550287dc062f.png](https://img-blog.csdnimg.cn/img_convert/407d7e482c11c2474c34550287dc062f.png)
2.2 内联结 INNER JOIN
内联结就是等值联结,只保留多个表里的交集数据。
![00399c277175261006db4ab8be1aa625.png](https://img-blog.csdnimg.cn/img_convert/00399c277175261006db4ab8be1aa625.png)
案例:
![ae4a87deba0a89c6636b32963ebb285d.png](https://img-blog.csdnimg.cn/img_convert/ae4a87deba0a89c6636b32963ebb285d.png)
2.3 左联结 LEFT JOIN
左联结是在多个表数据联结时保留下左边表的所有数据,和右边表满足关系条件的数据。
- 常见关系条件是相等关系(=)
![927c2de65c7435912244a866b2d5893a.png](https://img-blog.csdnimg.cn/img_convert/927c2de65c7435912244a866b2d5893a.png)
- 关系条件也可以是不等值关系(<,>,<=,>=,<>)
![38db7c4ee4793410af8e9bbeec3de612.png](https://img-blog.csdnimg.cn/img_convert/38db7c4ee4793410af8e9bbeec3de612.png)
- 只取左表仅有的数据
![f17dde64062bb90802d553cd1a85bd9d.png](https://img-blog.csdnimg.cn/img_convert/f17dde64062bb90802d553cd1a85bd9d.png)
案例:
![772bff1cccf672243abaa27ac8bb0ea6.png](https://img-blog.csdnimg.cn/img_convert/772bff1cccf672243abaa27ac8bb0ea6.png)
当多表联结的联结类型变化了一个,结果也不同:
![535b9c350c427fe3cf4f7dc0ca7db669.png](https://img-blog.csdnimg.cn/img_convert/535b9c350c427fe3cf4f7dc0ca7db669.png)
2.4 右联结 RIGHT JOIN
右联结是在多个表数据联结时保留下右边表的所有数据,和左边表满足关系条件的数据。
![106240f48895f62e16d7598934bdbcad.png](https://img-blog.csdnimg.cn/img_convert/106240f48895f62e16d7598934bdbcad.png)
案例:
![51bfaa91aa11ba162f9378441c2f9290.png](https://img-blog.csdnimg.cn/img_convert/51bfaa91aa11ba162f9378441c2f9290.png)
2.5 全联结 FULL JOIN
全联结查询结果是保留多个表里的所有行,满足联结关系条件的数据行合并只保留一次,待联结的表在其他表里匹配不到满足关系条件的数据时其他表里用null填充。
![2945f6cf9931f7b42e7d70e5abfcfebc.png](https://img-blog.csdnimg.cn/img_convert/2945f6cf9931f7b42e7d70e5abfcfebc.png)
(but,Mysql不支持全联结~~~)
3. JOIN语句练习
![d2e7ce4078e231171a36e11a2fd094dd.png](https://img-blog.csdnimg.cn/img_convert/d2e7ce4078e231171a36e11a2fd094dd.png)
![6c24275f1a79ec439c0de40b63dcce9a.png](https://img-blog.csdnimg.cn/img_convert/6c24275f1a79ec439c0de40b63dcce9a.png)
![4866967594db7446bd5c7f8219b1c39e.png](https://img-blog.csdnimg.cn/img_convert/4866967594db7446bd5c7f8219b1c39e.png)
4. 判断函数--CASE
应用场景:自定义分组、统计有筛选条件的数量等
- 语法一:
CASE 变量或要判断的字段或表达式
WHEN 常量1 THEN 要显示的值1(或语句1;)
WHEN 常量2 THEN 要显示的值2(或语句2;)
....
ELSE 要显示的值n(或语句n;)
END
当case语句放在select语句中作为表达式来使用时,此时case结构中就不能含有语句部分。
- 语法二:
CASE WHEN 条件1 THEN 要显示的值1(或语句1;)
WHEN 条件1 THEN 要显示的值2(或语句2;)
....
ELSE 要显示的值n(或语句n;)
END
- 语法一和语法二的区别在case后是否有内容,语法一是等值判断,when后省略等于号;语法二是区间判断。
- ELSE 可以省略,对应的结果会自动填充为NULL。
案例:
![9fe8b7732f9d9b3e3d06aca929e261df.png](https://img-blog.csdnimg.cn/img_convert/9fe8b7732f9d9b3e3d06aca929e261df.png)
![52502a82da20538cff287f61e6c06250.png](https://img-blog.csdnimg.cn/img_convert/52502a82da20538cff287f61e6c06250.png)
![d24efb188e5771a972f01f9446ce9585.png](https://img-blog.csdnimg.cn/img_convert/d24efb188e5771a972f01f9446ce9585.png)
5. sqlzoo练习
表信息如下:
赛事表game:
id(编号),mdate(日期),stadium(场馆),team1(队伍1编号),team2(队伍2编号)
入球表goal:
matchid(赛事编号),teamid(队伍编号),player(入球球员),gtime(入球时间)
欧洲队伍表eteam:
id(编号),teamname(队名),coach(教练)
![0c236f0311cac2eb83129101ac7ab36e.png](https://img-blog.csdnimg.cn/img_convert/0c236f0311cac2eb83129101ac7ab36e.png)
题目如下:
#1.列出 賽事編號matchid 和球員名 player ,該球員代表德國隊Germany入球的。
SELECT matchid,player
FROM goal
WHERE teamid='GER';
#2.由以上查詢,你可見Lars Bender's 於賽事 1012入球。.現在我們想知道此賽事的對賽隊伍是哪一隊。只顯示賽事1012的 id, stadium, team1, team2
SELECT id,stadium,team1,team2
FROM game
WHERE id='1012';
#3.顯示每一個德國入球的球員名,隊伍名,場館和日期。
SELECT player,teamid,stadium,mdate
FROM goal AS a
INNER JOIN game AS b ON a.matchid=b.id
WHERE a.teamid='GER;
#4.列出球員名字叫Mario (player LIKE 'Mario%')有入球的 隊伍1 team1, 隊伍2 team2 和 球員名 player。
SELECT team1,team2,player
FROM game AS a
INNER JOIN goal AS b ON a.id=b.matchid
WHERE player LIKE'Mario%';
#5.列出每場球賽中首10分鐘gtime<=10有入球的球員 player, 隊伍teamid, 教練coach, 入球時間gtime
SELECT player,teamid,coach,gtime
FROM goal AS a
INNER JOIN eteam AS b ON a.teamid=b.id
WHERE gtime<10;
#6.列出'Fernando Santos'作為隊伍1 team1 的教練的賽事日期,和隊伍名。
SELECT mdate,teamname
FROM eteam AS a
INNER JOIN game AS b ON a.id=b.team1
WHERE coach='Fernando Santos';
#7.列出場館 'National Stadium, Warsaw'的入球球員。(!注意名字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.列出全部賽事,射入德國龍門的球員名字。
SELECT DISTINCT player
FROM game AS a
INNER JOIN goal AS b ON a.id=b.matchid
WHERE (team1='GER'
OR team2='GER')
AND teamid!='GER';
#9.列出隊e伍名稱 teamname 和該隊入球總數
SELECT teamname,COUNT(player)
FROM eteam AS a
INNER JOIN goal AS b ON a.id=b.teamid
GROUP BY teamname;
#10.列出場館名和在該場館的入球數字。
SELECT stadium,COUNT(player)
FROM game AS a
INNER JOIN goal AS b ON a.id=b.matchid
GROUP BY stadium;
#11.每一場波蘭'POL'有參與的賽事中,列出賽事編號 matchid, 日期date 和入球數字。
SELECT matchid,mdate,COUNT(teamid)
FROM game AS a
INNER JOIN goal AS b ON a.id=b.matchid
WHERE team1='POL'
OR team2='POL'
GROUP BY matchid,mdate;
#12.每一場德國'GER'有參與的賽事中,列出賽事編號 matchid, 日期date 和德國的入球數字。
SELECT matchid,mdate,COUNT(teamid)
FROM game AS a
INNER JOIN goal AS b ON a.id=b.matchid
WHERE (team1='GER'
OR team2='GER')
AND teamid='GER'
GROUP BY matchid,mdate;
#13. 查出所有比赛日期,每场比赛双方各自的进球数。
SELECT a.mdate,
a.team1,
SUM(CASE WHEN b.teamid=a.team1 THEN 1 ELSE 0 END)AS score1,
a.team2,
SUM(CASE WHEN b.teamid=a.team2 THEN 1 ELSE 0 END)AS score2
FROM game AS a
LEFT JOIN goal AS b
ON a.id=b.matchid
GROUP BY a.mdate,a.team1,a.team2
ORDER BY a.mdate,a.id,a.tea