zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    关于OI的文学作品
    HBOI 2020 游记
    从0开始的字符串生活(选手命要没了)
    近两年HBOI选做
    NOI online #3
    2020年“美团杯”程序设计挑战赛题解(目前只有测试赛)
    退群咕咕墙
    JS 获得当前地址栏url
    你了解getBoundingClientRect()?
    字符串与数字相加
  • 原文地址:https://www.cnblogs.com/chenjieyouge/p/12702151.html
Copyright © 2011-2022 走看看