mysql 两个没有关联的表查询_数据


终于从单表查询“进化”到多表了,这个部分其实重点就是怎么把两张表或者多张表结合到一起,找到自己想要的结果。

这也是实际工作当中最经常用到的功能,就好像我也经常在SharePoint上面通过AJAX来获取多表数据合并处理类似,需要考虑清楚

如何将两(几)张表结合在一起,哪一(几)列是关键列,可以相互映射;
虚拟的联结表是否有空值,如何判断或使用;
最终拿到的结果是否是自己需要的结果,如何处理错误等等。

现在就开始!

本周笔记:


mysql 两个没有关联的表查询_SQL_02


练习1:如何合并两个表

  • 创建新表


mysql 两个没有关联的表查询_SQL_03

通过复制课程表来创建新表

mysql 两个没有关联的表查询_数据_04

改名为course1

mysql 两个没有关联的表查询_三张表关联查询统计_05

修改为如图数据备用

  • union合并查询


mysql 两个没有关联的表查询_三张表关联查询统计_06


  • union all合并查询


mysql 两个没有关联的表查询_SQL_07


练习2:内联结

  • 通过内联结查询学生学号、姓名、课程号以及成绩


mysql 两个没有关联的表查询_数据_08


练习3:左联结

  • 通过左联结查询学生学号、姓名、课程号以及成绩


mysql 两个没有关联的表查询_mysql 两个没有关联的表查询_09


  • 通过左联结查询学生学号、姓名、课程号以及成绩,并去除空值


mysql 两个没有关联的表查询_mysql 两个没有关联的表查询_10


练习4:右联结

  • 通过右联结查询学生学号、姓名、课程号以及成绩

为了使得结果较为明显,我在成绩表内添加了一行新数据,并在得出结果后删除:


mysql 两个没有关联的表查询_SQL_11


查询结果如下:


mysql 两个没有关联的表查询_SQL_12


  • 通过右联结查询学生学号、姓名、课程号以及成绩,并去除空值


mysql 两个没有关联的表查询_mssql 查询无记录时sum_13


练习5:联结应用

  • 查询所有学生的学号、姓名、选课数、总成绩

翻译成自己能看明白的大白话

学号、姓名可以由学生表student获取
选课数可以由成绩表score中通过学号分组,并使用count(课程号)获取
总成绩可以由成绩表score中通过学号分组,并使用sum(成绩)获取
由于需要使用多个表中查找数据,需要使用联结

分析思路

select 学号, 姓名, 选课数, 总成绩 from student [join] score -> 此处需要具体考虑需要什么联结,因为我们的题目是“所有的学生”故而使用左联结:left join on student.学号 = score.学号 -> 关键字(联结值)是两个表中的学号 where <查询条件> -> 无 group by student.学号 ->通过学号来分组 having <分组结果条件> -> 无 order by <排序条件> -> 无 limit <指定行> -> 无

写出SQL语句


-- 查询所有学生的学号、姓名、选课数、总成绩


运行结果


mysql 两个没有关联的表查询_mysql 两个没有关联的表查询_14


  • 查询平均成绩大于85的所有学生的学号、姓名和平均成绩

翻译成自己能看明白的大白话

学号、姓名可以由学生表student获取
选课数可以由成绩表score中通过学号分组,并使用count(课程号)获取
平均成绩可以由成绩表score中通过学号分组,并使用avg(成绩)获取
使用having对分组指定条件:平均成绩>85
由于需要使用多个表中查找数据,需要使用联结

分析思路

select 学号, 姓名, 选课数, 平均成绩 from student [join] score -> 此处需要具体考虑需要什么联结,因为我们的题目是“所有的学生”故而使用左联结:left join on student.学号 = score.学号 -> 关键字(联结值)是两个表中的学号 where <查询条件> -> 无 group by student.学号 ->通过学号来分组 having avg(score.成绩) > 85 -> 指定分组条件 order by <排序条件> -> 无 limit <指定行> -> 无

写出SQL语句


-- 查询所有学生的学号、姓名、选课数、总成绩


运行结果


mysql 两个没有关联的表查询_mssql 查询无记录时sum_15


  • 查询学生的选课情况:学号、姓名、课程号、课程名称

翻译成自己能看明白的大白话

学号、姓名可以由学生表student获取
课程号以及课程名称可以由课程表course获取
由于需要使得学号和课程号产生关联,还需要从成绩表score当中获取两者关系,即:
student.学号 = score.学号
score.课程号 = course.课程号
由于需要使用多个表中查找数据,需要使用联结

分析思路

select 学号, 姓名, 课程号, 课程名称 from student [join] score -> 此处需要具体考虑需要什么联结,考虑到需要在三张表中获取信息,尽量不要有空值,故选择:inner join on student.学号 = score.学号 -> 关键字(联结值)是两个表中的学号 [join] course on score.课程号 = course.课程号 -> inner join,关键字是课程号 where <查询条件> -> 无 group by <分组列名> -> 无 having <分组结果条件> -> 无 order by <排序条件> -> 无 limit <指定行> -> 无

写出SQL语句


-- 查询学生的选课情况:学号、姓名、课程号、课程名称


运行结果


mysql 两个没有关联的表查询_mssql 查询无记录时sum_16


练习6:case表达式

  • 查询出每门课程的及格人数和不及格人数

翻译成自己能看明白的大白话

课程号,成绩,学号可以由成绩表score获取
根据课程号分组
需要使用case表达式判断出某学号是否及格,并通过统计函数得到人数

分析思路

select 课程号, sum(case when 成绩 >= 60 then 1 else 0 end) as 及格人数, sum(case when 成绩 < 60 then 1 else 0 end) as 不及格人数 -> 统计函数使用sum,分别使用case表达式判断出及格和不及格的人 from score -> 由成绩表取值 where <查询条件> -> 无 group by 课程号 -> 通过课程号分组 having <分组结果条件> -> 无 order by <排序条件> -> 无 limit <指定行> -> 无

写出SQL语句


-- 查询出每门课程的及格人数和不及格人数


运行结果


mysql 两个没有关联的表查询_SQL_17


  • 使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计:各分数段人数,课程号和课程名称

翻译成自己能看明白的大白话

分数段即成绩,课程号,可以由成绩表score获取
课程名称则可以由课程表course获取
需要统计各科成绩,则需要通过课程号分组
需要使用case表达式判断出各个学号在各课程号中,其成绩所属的成绩段,并通过统计函数计算人数
因为需要从多张表中获取数据,故需使用联结

分析思路

select 课程号, 课程名称,   sum(case when 成绩 between 85 and 100 then 1 else 0 end) as '[100-85]',   sum(case when 成绩 between 70 and 85 then 1 else 0 end) as '[85-70]',   sum(case when 成绩 between 60 and 70 then 1 else 0 end) as '[70-60]',   sum(case when 成绩 < 60 then 1 else 0 end) as '[<60]'    -> 统计函数使用sum,分别使用case表达式判断出各个分数段的人   from score [join] course   -> 此处需要具体考虑需要什么联结,考虑到需要获取所有课程的人数,故选择:right join   on score.课程号 = course.课程号   -> 关键字(联结值)是两个表中的课程号   where <查询条件>   -> 无   group by score.课程号   -> 通过课程号分组   having   <分组结果条件>    -> 无   order by <排序条件>    -> 无   limit <指定行>    -> 无

写出SQL语句


/*


运行结果


mysql 两个没有关联的表查询_三张表关联查询统计_18



SQL Zoo练习题

  • 第一题


mysql 两个没有关联的表查询_SQL_19


  • 第二题


mysql 两个没有关联的表查询_SQL_20


  • 第三题


mysql 两个没有关联的表查询_数据_21


单独使用join时,其实它等价于inner join;同时因为列名不同,故而此处[表名.列名]省略为[列名]

  • 第四题


mysql 两个没有关联的表查询_mssql 查询无记录时sum_22


  • 第五题


mysql 两个没有关联的表查询_SQL_23


  • 第六题


mysql 两个没有关联的表查询_三张表关联查询统计_24


  • 第七题


mysql 两个没有关联的表查询_mysql 两个没有关联的表查询_25


  • 第八题


mysql 两个没有关联的表查询_mysql 两个没有关联的表查询_26


  • 第九题


mysql 两个没有关联的表查询_数据_27


  • 第十题


mysql 两个没有关联的表查询_数据_28


  • 第十一题


mysql 两个没有关联的表查询_mssql 查询无记录时sum_29


  • 第十二题


mysql 两个没有关联的表查询_三张表关联查询统计_30


  • 第十三题

列出每场赛事的比分表,包括比赛日期、球队1、比分1、球队2、比分2;按照比赛日期、比赛编号、球队1以及球队2进行排序

该题比较复杂,故而使用三步分析法:

翻译成自己能看明白的大白话

比赛日期mdate、球队team1和team2可以从比赛表game中获取
比分,即进球数可以从进球表goal中获取,并在进球球队与比赛中某只球队相同的情况下进行统计
需要通过比赛日期和球队来分组
需要按照题目要求进行排序

分析思路

select 比赛日, 球队1, sum(case when 进球球队 = 球队1 then 1 else 0 end) as 比分1, 球队2, sum(case when 进球球队 = 球队2 then 1 else 0 end) as 比分2 -> 统计函数使用sum,分别使用case表达式判断出球队双方在比赛中的进球数 from game [join] goal -> 此处需要具体考虑需要什么联结,考虑到需要获取所有比赛两只队伍的比分,故选择:left join on game.id = goal.matchid -> 关键字(联结值)是两个表中的比赛编号 where <查询条件> -> 无 group by game.比赛日, game.球队1, game.球队2 -> 通过比赛日、球队1和球队2进行分组 having <分组结果条件> -> 无 order by game.比赛日, goal.比赛编号, game.球队1, game.球队2 -> 按照题目要求进行排序 limit <指定行> -> 无

写出SQL语句


/*


运行结果


mysql 两个没有关联的表查询_mysql 两个没有关联的表查询_31


这里一定要留意到题目需要的是每一场赛事,故而不能再使用join (inner join),而使用left join

以上,全部练习完成!

究竟该使用哪一种联结方式(inner, left, right)是该部分非常非常重要的条件,很有可能一个不留神就用错了联结方式从而得出了错误的结论,尤其是SQL Zoo的Join练习13,如果还延用之前默认使用的内联结来做题,就会意外地发现原来有两场赛事是完全没有任何进球的,故而出错了。

所以必须要详细的分析每个关键条件,详细的写下分析思路,再来写SQL语句,会更容易找到正确的方法。