sql join中能否使用case when_SQL:多表查询

目录

一、 表的加法

二、 表的联结

  1. 交叉联结(笛卡尔积)
  2. 内联结
  3. 左联结
  4. 右联结
  5. 全联结

三、联结应用案列

四、 case表达式

一 、表的加法

加法:union(把两个表的查询语句合并在一起,会删除重复的数据)

605063946d58835464053cc42e721b26.png

union all(把两个表的查询语句合并在一起,不会删除重复的数据)

173a6dbdb702f404bce660ae4cbe46f2.png

二、表的联结

两个表之间产生关系的联结(join)

school中四张表之间的关系:

5910f6b80c02e53e3e413f705815c4e3.png

1.交叉联结(笛卡尔积cross join)

把表中的每一行,与另一个表中的每一行合并在一起。是所有联结的基础。

但在实际业务中较少运用,产生的结果行数过多,需要花费大量的运算成本、设备支持,且价值较低。

例:

  1. 表1(3行数据)【交叉联结】表2(2行数据)=6行数据(2x3)
  2. 生活中常见的交叉联结:扑克牌。花色x数字,即4x13=52张

2. 内联结(inner join)

查找出同时存在于两张表中的数据。选取出对应数据后会进行交叉联结。

26d8762780d84485c7b7cc6fcd1c0d00.png

a3025ed7581eda6f872ae0dd768712a8.png

a8aabb7b7ae28953c7e214b7df81064d.png

①在列名前面加上表名(参考②的说明)+一个点‘.’,可以区分这个列是哪个表的。

②from语句中,用了2张表,由于表明过长会影响sql的可读性,所以对表分别起了别名‘a’‘b’。

③from后的子句 on ,说明是通过哪个列进行联结的。

3. 左联结(left join)

会将左侧表中的数据全部取出来。将左侧的表作为主表,主表中的数据会全部读取出来,右边的表会选出与左侧的行的数据对应的行。

df027431c9fd78f10e0b29522c6b64e0.png

5c411c170a80414d65a8b62a438b5a42.png

4.右联结(right join)

85aa0f749f67f25c5e0d778d50032d2f.png

5. 全联结(full join) 注:Mysql不支持全联结

全联结的查询结果会返回左表与右表中的所有行,当某行与另一个表中的行有匹配的时候,会把两个行进行合并,如果某一行与另一个表中没有匹配的时候,另一个表中对应的地方会用空值(null)进行填充。

0cf44c7682f57d8c82799381bc7259b6.png

当实际工作业务中,想要生成固定行数的表单或者特别说明了要哪一张表中的全部数据的时候,会使用左联结或者右联结;其他情况都用内联结来获取两个表的公共部分。

76b38a5acf4d85b6a57ba329ac79c47b.png

三、联结应用案例

问题一:查询所有学生的学号、姓名、选课数、总成绩

分析思路:翻译成白话

  1. 学号、姓名(学生表student)
  2. 选课数(每个学生的选课数目:成绩表score;按学号分组,对课程号计数count)
  3. 总成绩(每个学生的总成绩:成绩表score;按学号分组,对成绩求和sum)

分析思路:按照sql运行顺序写出思路

961454889d726f4e3c2122d8a8f89296.png

1d60ed79699015b0a78b779d06bb9b36.png

问题二:查询平均成绩大于85的所有学生的学号、姓名、平均成绩

分析思路:翻译白话

  1. 平均成绩>85
  2. 查询所有学生的学号、姓名(学生表student),平均成绩(成绩表score,按学号分组,平均成绩:avg)

36e0d91590fc205a2e20fbd49848a4cf.png

错误说明:①两个语句的运行顺序没有掌握清楚

where(查询语句)在前,group by(分组)在后;

②应该用having(条件语句),having在group by后面运行。

06eaf3c00b1969a01417655a2e2c594d.png

问题三:查询学生的选课情况(学号、姓名、课程号、课程名称)

分析思路:翻译白话

  1. 学号、姓名(学生表student)
  2. 课程号、课程名称(课程表course)
  3. 但是两个表没有联结的列,选取成绩score作为联结

dec902bbf09d207bcdc08cd668ed156c.png

或者inner join 与 on 对应写在一起

3c1e04e1b9ed94b3e37bb5c41c4711b6.png

四、case表达式

可以帮助解决复杂的查询问题,用来判断某一行是否满足某个条件。

当有多种情况需要条件判断时,会使用case表达式。

case when <判断表达式> then <表达式>
     when <判断表达式> then <表达式>
     when <判断表达式> then <表达式>
     ...
     else <表达式>
end

第一行开始判断,如果符合第一个when的判断表达式,则运行后面的then表达式,结束;如果不符合第一个when的判断表达式,则开始第二行(与第一行同样的顺序),如果一直没有符合的判断表达式,则一直运行,直到执行else的表达式,结束。

else可以不写,默认为空值,最好写上。end不要省略。

问题一:查询每门课程的及格人数和不及格人数

f230e95a82452e77b8de1400e2e5e5b3.png

问题二:使用分段[100-85],[85-70],[70-60],[60>]统计各科成绩,分别统计各分数段人数、课程ID和课程名

10ea99f2314b7151326122fab566a7e6.png

注意:①在命名该列的名字,即列的别名中,存在中文的时候要加上引号'';

②当时用范围限定的时候,还可以使用between and 来表示,此处可以表达为between 60 and 75,但是用between and表示时,两端的值都是包括的,所以需要视情况使用。

③用group by分组时,应该与select语句中所要列出的列名表示一致,所以在分组时又加上了“课程名称”,此处分组的结果并不受影响。但当多个列来分组时,这几个列的值全部相同时才算一组。

SQLZOO练习:

68cc5af20ddcd27bef4faeacc8d16d99.png

5748c80b1b899f4dd17e80ac0043dbb8.png

9096317f58b02ffb0ddc71c3d9fbce6c.png

f8bdf43b565e64af8de9f1604bedcda3.png

efa70ee96e12a84bc0ded21ebb0c990e.png

a1bf44ad4c5d890e95ae052787116eeb.png

3f014647e38b7f544c4e6d05d84cb233.png

921375a7f53a7f4e5ce2e5dbbd4e0715.png

ps:①此处的内联结会出现重复的player,因此用distinct去掉重复值

②把德国队对手进球的情况都分别列出来

254720dc017a7fd8b6c00165b0c724ae.png

c00e27a05fd507318f0abdf17a2c30a0.png

c0ddbc7ebe571b4d29f204f5aafba15e.png

50808ffe648335c25940d93918975234.png

11、12两个都应该注意对最后的结果分组,(一般分组应按照select中的列名分组)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值