一、集合运算
集合运算:对满足同一规则的记录进行的加减等四则运算。
UNION以行
(纵向)为单位进行操作,而
JOIN以列
(横向)为单位进行操作。
1.表的加法(UNION)
两个表的结构相同,存放的数据不一样,可以使用表的加法将两个表的数据按行加在一起。
如果要在结果中保留重复行,只需要在UNION后面添加ALL关键字。
注意事项:
- 表的列数必须相同;
- 列的类型必须一致;
- 可以使用任何SELECT语句,但是ORDER BY子句只能在最后使用一次。
其他:
- 表的减法:EXCEPT/MINUS(差集);
- 选取表的公共部分:INTERSCECT(交集);
-
上面两个语法与UNION相同,只是MYSQL暂不支持。这些运算的特征是
以行方向
为单位进行操作,不会导致列数的增减。
2.表的联结(JOIN)
表的联结就是通过表和表之间的关系,将表合并到一起。也就是将其他表中的列添加过来,进行
添加列
的运算。
常用联结:
1)内联结(INNER JOIN)
查找出同时存在于两张表中的数据,是应用最广泛的联结运算。
要点:
- 对原表命名别名不是必须的,但是表名太长可能会影响SQL语句的可读性,因此建议使用别名;
- ON是必不可少的,起到和WHERE相同的作用,书写时须在FROM和WHERE之间;需要指定多个键时,也可以使用AND和OR。
2)左联结(LEFT JOIN)和右联结(RIGHT JOIN)
左联结
:以左表为主表,将左侧表中的数据全部取出来。
右联结
:将右侧表中的数据全部取出来
3)交叉联结(CROSS JOIN)-笛卡尔积
将表中的每一行都与另一张表的每一行合并在一起。在实际业务中几乎不会使用。
4)全联结(FULL JOIN)
返回两张表的所有行,如某一行有匹配就数据合并,没有就用空值填充。MYSQL不支持全联结。
5)多表联结
可以使用INNER JOIN进行添加,原则上联结表的数量是没有限制的。
总结
二、联结应用案例
1.查询所有学生的学号、姓名、选课数和总成绩
2.查询平均成绩大于85分的所有学生的学号、姓名和平均成绩
3.查询学生的选课情况:学号,姓名,课程号,课程名称
三、CASE表达式
CASE表达式用来解决复杂的查询问题,是一种条件判断的函数。CASE表达式会从最初的WHEN子句中的<判断表达式>求值开始执行。如果符合某个条件,就运行后面的THEN子句,若不符合条件,继续运行下一条WHEN子句,直到返回ELSE中的表达式,执行终止。CASE表达式是
SQL中极其重要
的功能。
CASE WHEN <判断表达式>THEN<表达式>
WHEN <判断表达式>THEN<表达式>
WHEN <判断表达式>THEN<表达式>…
ELSE<表达式>
END
举例:
1.在查询结果中显示成绩是否及格
2.查询出每门课程的及格人数和不及格人数
注意事项:
- CASE表达式中的ELSE子句可以省略,但是防止漏读,还是建议写出来;
- END不能省略;
- CASE表达式可以写在SQL中任意地方。
3.使用分段[100-85]、[85-70]、[70-60]、[<60]来统计各科成绩。分别统计:课程号、课程名称和各分数段人数
四、练习:
SQLZOO
The JOIN operation
1.show thematchidandplayername for all goals scored by Germany. To identify German players, check for:teamid = 'GER'.
SELECT matchid,player FROM goal
WHERE teamid = 'GER';
2.Show id, stadium, team1, team2 for just game 1012.
SELECT id,stadium,team1,team2
FROM game
WHERE id = '1012';
3.show the player, teamid, stadium and mdate for every German goal.
SELECT player,teamid,stadium,mdate
FROM game INNER JOIN goal ON id=matchid
WHERE teamid = 'GER';
或 SELECT b.player,b.teamid,a.stadium,a.mdate
FROM game AS a INNER JOIN goal AS b
ON a.id=b.matchid
WHERE teamid = 'GER';
4.Show the team1, team2 and player for every goal scored by a player called Mario player LIKE 'Mario%'.
SELECT a.team1,a.team2,b.player
FROM game AS a INNER JOIN goal AS b
ON a.id=b.matchid
WHERE b.player LIKE 'Mario%';
5.Show player, teamid, coach, gtime for all goals scored in the first 10 minutes gtime<=10.
SELECT a.player, a.teamid, b.coach, a.gtime
FROM goal AS a INNER JOIN eteam AS b
ON a.teamid=b.id
WHERE a.gtime<=10;
6.List the dates of the matches and the name of the team in which 'Fernando Santos' was the team1 coach.
SELECT a.mdate, b.teamname
FROM game AS a INNER JOIN eteam AS b
ON a.team1 = b.id
WHERE coach = 'Fernando Santos';
7.List the player for every goal scored in a game where the stadium was 'National Stadium, Warsaw'.
SELECT a.player
FROM goal AS a INNER JOIN game AS b
ON a.matchid = b.id
WHERE stadium = 'National Stadium, Warsaw';
8.show the name of all players who scored a goal against Germany.
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.Show teamname and the total number of goals scored.
SELECT c.teamname, COUNT(b.player)
FROM goal AS b INNER JOIN eteam AS c ON b.teamid = c.id
GROUP BY c.teamname;
10.Show the stadium and the number of goals scored in each stadium.
SELECT a.stadium, COUNT(b.player)
FROM game AS a INNER JOIN goal AS b ON a.id = b.matchid
GROUP BY a.stadium;
11.For every match involving 'POL', show the matchid, date and the number of goals scored.
SELECT b.matchid,a.mdate,COUNT(b.player)
FROM game AS a INNER JOIN goal AS b ON b.matchid = a.id
WHERE (team1 = 'POL' OR team2 = 'POL')
GROUP BY b.matchid,a.mdate;
12.For every match where 'GER' scored, show matchid, match date and the number of goals scored by 'GER'.
SELECT b.matchid,a.mdate,COUNT(b.player)
FROM game AS a INNER JOIN goal AS b ON b.matchid = a.id
WHERE b.teamid = 'GER'
GROUP BY b.matchid,a.mdate;
13.List every match with the goals scored by each team as shown. Sort your result by mdate, matchid, team1 and team2.
SELECT a.mdate,
a.team1,SUM(CASE WHEN a.team1=b.teamid THEN 1 ELSE 0 END) AS score1,
a.team2,SUM(CASE WHEN a.team2=b.teamid THEN 1 ELSE 0 END) AS score2
FROM game AS a LEFT JOIN goal AS b ON b.matchid = a.id
GROUP BY a.id,a.mdate,a.team1,a.team2
ORDER BY a.mdate,a.id,a.team1,a.team2;