首页 > 数据库技术 > 详细

SQL 强化练习 (十二)

时间:2020-04-15 01:19:12      阅读:87      评论:0      收藏:0      [点我收藏+]

还是 sql 冲鸭... , 停不下来了都, 趁着激情还在, 赶紧再整一把, 也渐渐发现, sql 果然是非常强大的, 然后搞了半天, 发现在写sql 的时候, 从它执行顺序来思考, 这样反而会轻松很多哦.

表关系

技术分享图片

需求 01

查询 每门课程 被选修的学生人数

分析

纯练练手而已, 毫无难度. 还是不断在强调关于 group by 的用法, 即, 用了 group by 后, select 的字段必须是在 group by 中 或者 是聚合函数. 不然则报错或引发歧义, 这个非常重要. 然后就是新手,比如像我这种, 分组筛选的. where 是在 group by 之前, having 是 group by 之后.

select 
  a.c_id,
  b.c_name,
  count(distinct a.s_id)


from score as a
inner join course as b 
  on a.c_id = b.c_id 
group by a.c_id, b.c_name 


+------+--------+------------------------+
| c_id | c_name | count(distinct a.s_id) |
+------+--------+------------------------+
| 0001 | 语文   |                      2 |
| 0002 | 数学   |                      3 |
| 0003 | 英语   |                      3 |
+------+--------+------------------------+
3 rows in set (0.00 sec)

mysql>

需求 02

查询 只有两门课程的全部学生的学号和姓名.

分析

先按 s_id 分组, 然后分组过滤(having) 出 课程数量为 2 的学号, 再匹配下学生表即可.

-- 先看有哪些学号

select * from score 
group by s_id
  having count(distinct c_id) = 2

+------+------+-------+
| s_id | c_id | score |
+------+------+-------+
| 0002 | 0002 |    60 |
+------+------+-------+
1 row in set (0.00 sec)

然后再做一个子查询, 作为学生表的一个筛选条件.

select
  s_id as 学号, 
  s_name as 姓名

from student where s_id in (

  select s_id 
  from score 
  group by s_id
    having count(distinct c_id) = 2
)
+--------+--------+
| 学号   | 姓名   |
+--------+--------+
| 0002   | 星落   |
+--------+--------+
1 row in set (0.01 sec)

拓展一波, 其实我现在, 反而是更加喜欢先多表连接的方式来弄, 这样对于更加复杂的逻辑, 也是能够处理的, 涉及的表都给它拼接起来, 要啥字段就拿啥字段, 随便玩..

select 
  b.s_id  学号,
  b.s_name  姓名

from score as a 
inner join student as b 
  on a.s_id = b.s_id

group by a.s_id
  having count(distinct a.c_id) = 2

我发现自己, 在写 join 的时候, 常常忘了 写 on 的条件, 就瞎连接...真是无语了.

+--------+--------+
| 学号   | 姓名   |
+--------+--------+
| 0002   | 星落   |
+--------+--------+
1 row in set (0.00 sec)

今天的这两个, 都是练手题, 蛮简单的, 还是关键在于掌握着两种思路, 一种是 "子查询" 风格的, 有点像咱编程的 面向过程写法; 另外一种是 "Join" 风格的, 将相关的表,都给关联上, 然后再来慢慢优化, 就跟咱编程的 "面向对象" 有点像, 差不多这样吧. 然后我发现, 现在还是挺喜欢后者这种 join 的方式的, 都先给怼出来, 然后再优化. 具体看场景吧还是.

小结

  • 从 sql 的执行顺序去写sql 会事半功倍, 兼顾 子查询 和 join 两种思维方式的结合
  • group by , select 中只能放 与 group by 的字段 或聚合函数, where > group by > having
  • join 的时候, on 理解为 True ... 如不写或 True 则是会全部连接起来..一定要写清楚 或者 多条件判断 结合 and 和 or

SQL 强化练习 (十二)

原文:https://www.cnblogs.com/chenjieyouge/p/12702151.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!