继续练习写sql, 不能停下来.

今天还额外对 Excel 拼接 sql 语句做了一个代码实现, 逻辑是蛮简单的, 发现其实很多东西都是蛮简单的, 只要一点点去做, 明白逻辑过后, 慢慢去调试, 都是可以弄出来的呀. 这就是解决问题的过程吧, 其实是快乐的, 尤其是当你开始写代码的那一刻, 心里已经想好了, 只是实现而已.

表关系

感觉练习上瘾了, 此种有真意哦, 莫非.

需求 01

查询 两门及其以上, 不及格课程的学生学号, 姓名, 平均成绩

分析

先来看一波, 不及格的信息 从score 中有哪些 s_id.

select s_id from studnet where score < 60;

咱的测试数据是没有符合记录的, 我也懒得加了, 就直接走吧, 关键是理清这个逻辑即可.

然后呢, 然后, 按学号 group by, 组后过滤出, 选课数量大于 2 的哪些 s_id

select s_id from student where score < 60
group by s_id having count(distinct c_id) >= 2;

然后, 拿到学生姓名和平均成绩, 那 学生表 和 成绩表 要 inner join 呀

select
st.s_id as "学号",
st.s_name as "姓名" from student as st
inner join score as sc
on st.s_id = sc.s_id -- 满足2门一上的学号(子查询)
where st.s_id in (
select s_id from student where score < 60
group by s_id having count(distinct c_id) >= 2
);

是空的,都不用运行, 测试数据中没有这方面的记录, 脑补一波就好, 不想增加了.

最后是, 平均成绩 要对 s_id 做 group by 了. s_name 也要加上, 不然可能会报错的,因为, s_name 出现在了 select 中, 而并未出现在 group by 中, 这样二者是有问题的. 做了 group by 后, select 只能放跟 group by 中的字段 或者是聚合函数.

select
st.s_id as "学号",
st.s_name as "姓名", avg(s_score) as "平均成绩" from student as st
inner join score as sc
on st.s_id = sc.s_id -- 满足2门一上的学号(子查询)
where st.s_id in (
select s_id from student where score < 60
group by s_id having count(distinct c_id) >= 2
) group by s_id, s_name;

总体思路, 就是先子查询出, 那些 score < 60 and 选课数 > 2 的这些学号; 最后作为 in.

然后学生表 和 score 做 inner join -> 满足学号的那些记录后, 再进行 group by 学号, 姓名 对 avg(score) 就搞定了.

需求 02

查询 "0001" 课程 分数小于95按分数降序排列学生的信息

分析

这个就简单了呀. 关联 student 和 score 然后 where 后, order by 即可呀

mysql> select * from 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)

就是 1, 3 号同学呗.

select
a.*,
b.score
from student as a
inner join score as b
on a.s_id = b.s_id where
b.c_id = "0001" and b.score < 95
-- 最后再降序按 score
order by b.score;
+------+-----------+------------+--------+-------+
| s_id | s_name | birth_date | gender | score |
+------+-----------+------------+--------+-------+
| 0001 | 王二 | 1989-01-01 | 男 | 80 |
| 0003 | 胡小适 | 1991-12-21 | 男 | 80 |

仔细想想, 平时业务中写的一些 sql 本质上也是这些 学生表, 成绩表 的 join, 子查询 , 过滤, 排序而已, 因此, 掌握这类的思维逻辑, 和写法就已经成功一大半了.

嗯, 我最近反而是一设计多表关联的, 就想写成套娃的形式, 就是很多最后再来一个大括号, 有点像写 Java 那种感觉, 主函数, 然后在私有方法, 变量, 再 子函数... 这样一层层套下去哦.

select * from 

(select
a.*,
c_id,
b.score
from student as a
inner join score as b
on a.s_id = b.s_id) as c where score < 95 and c_id = "0001"
order by score desc;
+------+-----------+------------+--------+-------+
| s_id | s_name | birth_date | gender | score |
+------+-----------+------------+--------+-------+
| 0001 | 王二 | 1989-01-01 | 男 | 80 |
| 0003 | 胡小适 | 1991-12-21 | 男 | 80 |

核心点就是,将最后的输出前的东西, 给拼成一张大表来取字段数据, 这样的好处是, 最后可以不用别名来找字段, 但问题是在拼接的时候, 对于列的选取, 重复列都是好好考虑的点. 想想, 还是别名的方式吧, 这样可能会更加稳一点.

对于这个题, 其是还有种情况, 在做 inner join 的时候, 是将其默认为 1: 1 的关系, 那如果是 1: n 也是可以的. 但如果是 n: n 的关系, 这就不好弄了呀. 就多尝试一下, 没啥问题就这样吧.

小结

  • 对于某些条件的, 可以先给 子查询出来,然后慢慢去 关联表, 过滤, 分组等操作
  • 多表连接的套娃写法, 咋说呢, 就真的很容易去混淆, 尤其是多层嵌套以后, 注意别名非常关键哦.
  • sql 顺序:
    • 写法: select ... from ... group by ...having ... select ... order by ... limit
    • 执行: from ... where ... group by ... having ... select ... order by ... limit

以前, 我是新手嘛, 就在 group by 后, 到底 where 放在 group by 之后... 想想都蠢, 根本就没有意义的呀. 慢慢想这个过程, 就大致能理清楚了, 还是要多加练习哦.

SQL 强化练习 (八)的更多相关文章

  1. SQL入门经典(八) 之存储过程

    存储过程(stored procedure)有时候称为sproc,它是真正的脚本-或者更准确的说,他是批处理(batch)-它存储于数据库中,而不是淡出的文件中.无论如何,这个比较并不是很确定.存储过 ...

  2. SQL强化(一)保险业务

    保险业务 : 表结构 : sql语句 : /*1. 根据投保人电话查询出投保人 姓名 身份证号 所有保单 编号 险种 缴费类型*/SELECTt2.cust_name,t2.idcard,t4.pro ...

  3. SQL强化练习(面试与学习必备)

    一.经典选课题A 1.1.请同时使用GUI手动与SQL指令的形式创建数据库.表并添加数据. 题目:设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教 ...

  4. SQL学习笔记八之ORM框架SQLAlchemy

    阅读目录 一 介绍 二 创建表 三 增删改查 四 其他查询相关 五 正查.反查 一 介绍 SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进 ...

  5. Spark SQL概念学习系列之Spark SQL入门(八)

    前言 第1章   为什么Spark SQL? 第2章  Spark SQL运行架构 第3章 Spark SQL组件之解析 第4章 深入了解Spark SQL运行计划 第5章  测试环境之搭建 第6章 ...

  6. SQL系列(八)—— 分组(group by)

    在很多场景时,需要对数据按照某条件进行分组统计其数量.平均值等等.有这种需求,SQL自然也有解决方式. 在SQL中通过group by子句对结果按某条件进行分组.语法: select count(co ...

  7. Influx Sql系列教程八:query数据查询基本篇

    前面几篇介绍了InfluxDB的添加,删除修改数据,接下来进入查询篇,掌握一定的SQL知识对于理解本篇博文有更好的帮助,下面在介绍查询的基础操作的同时,也会给出InfluxSql与SQL之间的一些差别 ...

  8. Mysql常用sql语句(八)- where 条件查询

    测试必备的Mysql常用sql语句,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1683347.html 前言 ...

  9. SQL Server(八)——触发器

    触发器是一类特殊的存储过程,在对表update,insert或delete语句时自动执行, 没有参数,没有返回值: 一.触发器类型 1.for触发器 在动作执行之后触发(增删改执行完成后,触发器中的代 ...

  10. 必须会的SQL语句(八)数据库的完整性约束

    实体完整性 1.建表时定义主键   Create table 表名    (         Sno int identity(1,1),         Sname nvarchar(20),    ...

随机推荐

  1. 5. 想在代码中验证sql的正确性?

    1. 简介 我们在平时的开发中可能会遇到需要验证一下sql是否正确,也就是需要check一下sql. 判断sql是否正确一般包含一下几点: 1. sql中使用的列是否存在 2. sql语法是否正确 3 ...

  2. idea debug时提示”Method breakpoints may dramatically slow down debugging“的解决办法

  3. 解密ZAB协议:Zookeeper一致性的核心实现

    一致性问题 设计一个分布式系统必定会遇到一个问题-- 因为分区容忍性(partition tolerance)的存在,就必定要求我们需要在系统可用性(availability)和数据一致性(consi ...

  4. Kubernetes - [03] 安装部署

    Kubeadm 部署k8s集群 一.准备工作 1.1.组件 组件:Harbor(私有Docker Hub).Router 服务器操作系统:Centos7 +(内核3.0+,最好内核4.40+) 1.2 ...

  5. 【BUUCTF】Blacklist

    [BUUCTF]Blacklist (SQL注入) 题目来源 收录于:BUUCTF GYCTF2020 题目描述 纯粹的SQL注入题 当触发黑名单时返回如下 过滤了以下关键字 set prepare ...

  6. @autowired注解报错原因及解决办法

    @autowired 注入dao层的时候,标红报错,但不影响编译使用 按照严格的spring注解方式在dao层加入@Repository注解

  7. 全面的C#/.NET/.NET Core面试宝典(永久免费)

    前言 C#/.NET/.NET Core相关技术常见面试题汇总,不仅仅为了面试而学习,更多的是查漏补缺.扩充知识面和大家共同学习.携手进步. 该知识库主要由自己平时学习和工作实践总结.网上优秀文章资料 ...

  8. MySQL 8.0 语法记录

    SQL又杂又烦,记不住,网上搜到的语句还未必正确.这里做一个Record 基本操作 数据库操作 数据表操作 create index [索引名] on [表名]([列名]); /* 以选定列为索引信息 ...

  9. etcd和Zookeeper孰优孰劣对比

    背景 最近在看到Pachyderm的介绍时,看到作者拿YARN和Kubernetes做类比,拿Zookeeper和etcd做对比.YARN和Kubernetes的类比还相对比较好理解,毕竟他们都有资源 ...

  10. 学习Kotlin语法(四)

    简介 在上一节,我们对Kotlin中函数的相关知识有了大致的了解,本章节我们将去了解一些Kotlin中的作用域函数. 目录 let:处理可空对象,链式操作 run:对象配置 + 计算返回值 with: ...