SQL 日常练习(十五)

Posted 宁鸣而死

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL 日常练习(十五)相关的知识,希望对你有一定的参考价值。

这两周真的是被客户搞怕了, 我一个数据分析师, 干着比程序员还复杂的活, 拿着文员的工资, 看这我每天下班的打卡时间, 感觉我一点求生欲都没有,真的不知道图啥. 快速理解业务, 马上建数据库表, 写后台 sql, 然后做前台网页看板,, 还要帮业务写小程序, 和帮他们处理 Excel, 还要给他们爬数据... 这尼玛要我全能嘛? 尤其吐槽一波, 数据采集, 他们用的 RPA, 自动化ERP 这种没有接口的, 我觉得很强大, 但就操作下浏览器, 爬个数据, 搞来搞去,着实有些烦, 还要按流程写才让上线....我是欣赏不来. 我感觉有点low, 有种感觉就是, 好比我已经大学毕业2年了, 然后突然告诉我, 不合格, 要从头从大一开始读..... 这不是倒退嘛? 我肯定是不接受倒退的, 宁可止步不前, 绝不倒退.

数据采集 -> 数据清洗 -> 建数据库表 -> 业务逻辑 sql -> 业务前端网页看板 -> 额外编程支持...

虽然我都会了, 但就是不想弄. 有句话是这样说的,非常赞同, Where there is a will, there is a way. 就是, 一个人, 就我自己吧. 如果我想做一件事, 我一定会不断尝试去找一个方法; 如果我不想做, 我就会千方百计去找一个借口. 我现在就需要一个借口, 不, 很多借口..

吐槽完, 还是继续练习 sql, 虽然我工作中写的远比这些笔记复杂得多, 但仔细看,原理都差不多的. 练练而已, 就跟打字一样, 熟练到忘记怎么打为止

表关系

需求 01

查询 所有学生的课程 及分数情况

分析

case when 来进行将行变为列呗. sql 我都写套路化了, 先就是将涉及的表给 Join 起来, 最后再来字段, 要啥有啥.

select
from score as a
-- 匹配上课程名称, 学生信息
inner join course as b 
  on a.c_id = b.c_id 
inner join student as c 
  on a.s_id = c.s_i

然后拼成了大表后, 再来处理字段, 包括字段筛选, 字段清洗(函数) , 条件过滤, 分组聚合, 排序等骚操作.

这一看就是要用 学号和课程号进行 group by 的, score 也来 group by 吧

mysql> select
    ->    s_id,
    ->    c_id,
    ->    score
    -> from score
    -> group by s_id, c_id, score;
+------+------+-------+
| s_id | c_id | score |
+------+------+-------+
| 0001 | 0001 |    80 |
| 0001 | 0002 |    90 |
| 0001 | 0003 |    99 |
| 0002 | 0002 |    60 |
| 0002 | 0003 |    80 |
| 0003 | 0001 |    80 |
| 0003 | 0002 |    80 |
| 0003 | 0003 |    80 |
+------+------+-------+
8 rows in set (0.00 sec)

还是不断重复, group by 最为关键的一点, select 中的字段, 必需要在 group by 中出现过, 或者是 聚合函数, 否则就引发歧义了呀. 然后呢, 其实我们想要看到的结果, 应该是那种展开的, 就要将 c_id 对应的那些课程给它从行变为列字段来展示. 即对 c_id 进行 case when 即可.

select
  a.s_id as 学号,
  a.c_id as 课程号,
  c.s_name as 姓名,

  -- 将课程的行转为列,用 case when 的方式
  max(case when b.c_name="语文" then a.score else null end) as 语文,
  max(case when b.c_name="数学" then a.score else null end) as 数学,
  max(case when b.c_name="英语" then a.score else null end) as 英语

from score as a
-- 匹配上课程名称, 学生信息
inner join course as b 
  on a.c_id = b.c_id 
inner join student as c 
  on a.s_id = c.s_id

group by c.s_id, c.s_name

+--------+-----------+-----------+--------+--------+--------+
| 学号   | 课程号    | 姓名      | 语文   | 数学   | 英语   |
+--------+-----------+-----------+--------+--------+--------+
| 0001   | 0001      | 王二      |     80 |     90 |     99 |
| 0002   | 0002      | 星落      |   NULL |     60 |     80 |
| 0003   | 0001      | 胡小适    |     80 |     80 |     80 |
+--------+-----------+-----------+--------+--------+--------+
3 rows in set (0.00 sec)

我现在是可以很轻易写出来了, 因为我之前也跟着网上写了一遍了, 孰能生巧嘛, 果然如此, 又记住了, 正如艾宾浩斯说的那样, 记忆最好的方式, 就是重复.

不想练了, 我觉得这个 case when 就特别强大了. 还有今天还用到了一个 正则函数和 replace , 逐渐对 sql 有点感觉了, 就跟编程似乎差不多了. 我一直是感觉编程简单, sql 很难, 可是小伙伴们都不认同. 不管了, 都会就行了.多练习即可, 我想.

以上是关于SQL 日常练习(十五)的主要内容,如果未能解决你的问题,请参考以下文章

SQL日常练习-牛客网

SQL日常练习2-进阶篇-牛客网

SQL 日常练习 (十四)

SQL日常练习1-基础篇-牛客网

SQL日常练习2-进阶篇-牛客网

SQL 日常练习 (二十)