SQL 强化练习 (八)
继续练习写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 强化练习 (八)的更多相关文章
- SQL入门经典(八) 之存储过程
存储过程(stored procedure)有时候称为sproc,它是真正的脚本-或者更准确的说,他是批处理(batch)-它存储于数据库中,而不是淡出的文件中.无论如何,这个比较并不是很确定.存储过 ...
- SQL强化(一)保险业务
保险业务 : 表结构 : sql语句 : /*1. 根据投保人电话查询出投保人 姓名 身份证号 所有保单 编号 险种 缴费类型*/SELECTt2.cust_name,t2.idcard,t4.pro ...
- SQL强化练习(面试与学习必备)
一.经典选课题A 1.1.请同时使用GUI手动与SQL指令的形式创建数据库.表并添加数据. 题目:设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教 ...
- SQL学习笔记八之ORM框架SQLAlchemy
阅读目录 一 介绍 二 创建表 三 增删改查 四 其他查询相关 五 正查.反查 一 介绍 SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进 ...
- Spark SQL概念学习系列之Spark SQL入门(八)
前言 第1章 为什么Spark SQL? 第2章 Spark SQL运行架构 第3章 Spark SQL组件之解析 第4章 深入了解Spark SQL运行计划 第5章 测试环境之搭建 第6章 ...
- SQL系列(八)—— 分组(group by)
在很多场景时,需要对数据按照某条件进行分组统计其数量.平均值等等.有这种需求,SQL自然也有解决方式. 在SQL中通过group by子句对结果按某条件进行分组.语法: select count(co ...
- Influx Sql系列教程八:query数据查询基本篇
前面几篇介绍了InfluxDB的添加,删除修改数据,接下来进入查询篇,掌握一定的SQL知识对于理解本篇博文有更好的帮助,下面在介绍查询的基础操作的同时,也会给出InfluxSql与SQL之间的一些差别 ...
- Mysql常用sql语句(八)- where 条件查询
测试必备的Mysql常用sql语句,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1683347.html 前言 ...
- SQL Server(八)——触发器
触发器是一类特殊的存储过程,在对表update,insert或delete语句时自动执行, 没有参数,没有返回值: 一.触发器类型 1.for触发器 在动作执行之后触发(增删改执行完成后,触发器中的代 ...
- 必须会的SQL语句(八)数据库的完整性约束
实体完整性 1.建表时定义主键 Create table 表名 ( Sno int identity(1,1), Sname nvarchar(20), ...
随机推荐
- JS实现隐藏手机号码中间4位数
代码COPY 3. 使用正则 function geTel(tel){ var reg = /^(\d{3})\d{4}(\d{4})$/; return tel.replace(reg, " ...
- 【软件开发】vcpkg学习笔记
[软件开发]vcpkg 学习笔记 "vcpkg"是一个免费开源的 C++包管理器,可以以此很方便的处理第三方库的接入,且可嵌入进 CMake 中. 入门 入门教程请参照: http ...
- Docker安装及卸载小白教程(附基本使用命令)
第一种:宝塔面板 安装最新版宝塔面板,左侧docker进去安装,等着完成就好 第二种:命令安装 在终端root用户下,依次输入下方指令安装 1.yum包更新到最新 yum update 2.安装需要的 ...
- Kubernetes - [01] 概述
容器编排工具 一.什么是Kubernetes K8s,即Kubernetes,是一个开源的容器管理和自动化部署平台,设计用于简化容器化应用程序的部署.扩展和管理过程.它是Google在2014年基 ...
- Linux - centos6忘记root密码怎么办?
Linux的root密码修改不像Windows的密码修改找回,Windows的登录密码忘记需要介入工具进行解决.CentOS6和CentOS7的密码方法也是不一样的,具体如下 1.开机按esc 2 ...
- 百万架构师第四十五课:并发编程的基础|JavaGuide
课程目标 1. 多线程的发展历史 2. 线程的应用 3. 并发编程的基础 4. 线程安全的问题 特定的指令,计算机不会存储指令,把指令写下来,一次性读取指令,批处理. 然后我们需要把批处理进行隔离.保 ...
- HTTP请求中包含账号密码
如果你需要在HTTP请求中包含账号密码,你可以使用基本的HTTP身份验证.在C#中,你可以通过设置 HttpClient 的 DefaultRequestHeaders 来添加身份验证信息.以下是修改 ...
- 谷歌 Chrome 浏览器离线安装 vue devtools 插件
由于某些原因,Chrome 应用商店访问不了,所以只能离线安装 vue devtools 插件,离线安装也有两种方法. 方法一:自编译 vue devtools 插件 这方法要求动手能力强的同学. 前 ...
- [tldr]github仓库添加release
作为一个开源项目开发者,并且把自己的代码仓库托管到了github上面,所以,可以在github上提供自己的程序的release 这通常是通过二进制可执行文件的方式提供 新建草稿 点击create a ...
- DevEco Studio 常用设置【自用】
设置为中文 API参考设置悬浮 始终定位打开的文件,单击预览免打开 保存时自动格式化和热更新 属性单独一行