SQL 强化练习 (十二)

还是 sql 冲鸭... , 停不下来了都, 趁着激情还在, 赶紧再整一把, 也渐渐发现, 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 强化练习 (十二)

上一篇:UIWebView使用中的内存相关问题


下一篇:记一次 mysql模糊查询某个字段中文被unicode编码的方法