SQL 强化练习 (五)
果然日常练练这些 sql 是非常有必要的, 这几日的报表开发, 用一款过程软件 fineReport, 相对于我之前用 Tableau 来做报表, 这个帆软, 确实更加适合中国人哦, 而Tableau只是专门用来展示而已. 我感觉 FR, 还是有一定门槛的, 首先就是 SQL, 大量的操作都是需要写 sql 来完成的, 我还蛮喜欢的其实, 很灵活的嘛. 其实是要理解 WEB, 比如做填报, 就是要先弄个页面, 然后设计数据库, 单元格值回写数据库, 数据库查询报表展示... 这个就是 WEB 呀, 反正我觉得还是有些复杂的, 但核心技能 SQL 是必须的, 虽然这里用的更多是 查询方面. 还是得不断练习...
表关系

深深可在脑海中, 我感觉, 其实业务中也只不过是, 字段变多了, 表结构复杂一些而已, 本质是还是表呀.
需求 01
查询课程编号为 "0002" 的总成绩, 平均成绩, 人数等.
分析
这就是用来练习下聚合函数(sum, count, avg..)
select
sum(score) as "总成绩",
avg(score) as "平均成绩",
count(score) as "成绩总份数",
count(distinct s_id) as "学生人数"
from score
where c_id = "0002";
+-----------+--------------+-----------------+--------------+
| 总成绩 | 平均成绩 | 成绩总份数 | 学生人数 |
+-----------+--------------+-----------------+--------------+
| 230 | 76.6667 | 3 | 3 |
+-----------+--------------+-----------------+--------------+
感觉其实这个查询是没啥意义的, 就选一个一门课, 有啥号看的呢, 倒不如, 查看所有的课程的信息多好.
select
c_id as "课程编号",
sum(score) as "总成绩",
avg(score) as "平均成绩",
count(score) as "成绩总份数",
count(distinct s_id) as "学生人数"
from score
group by c_id;
+--------------+-----------+--------------+-----------------+--------------+
| 课程编号 | 总成绩 | 平均成绩 | 成绩总份数 | 学生人数 |
+--------------+-----------+--------------+-----------------+--------------+
| 0001 | 160 | 80.0000 | 2 | 2 |
| 0002 | 230 | 76.6667 | 3 | 3 |
| 0003 | 259 | 86.3333 | 3 | 3 |
+--------------+-----------+--------------+-----------------+--------------+
这样, 看全部的数据, 我感觉这更加贴和业务一点. 值得主要的是 group by 的用法, select 一般都先是这个 聚合字段的值, 然后再是一些聚合函数字段. 不要再select 放跟 分组字段 没有关系的字段. 这样经常会引发歧义和直接报错, group by -> aggregation... 这是必须要掌握的哦. 其次, 就是 group by 后面不要跟 where, 根本没有意义, where 必然是要放在 group by 之前呀, 而对于 分组后的过滤 用 having.
正好来练习一下: 用分组过滤 having 的方式来查看 "0002" 的信息
select
c_id as "课程编号",
sum(score) as "总成绩",
avg(score) as "平均成绩",
count(score) as "成绩总份数",
count(distinct s_id) as "学生人数"
from score
group by c_id having c_id = "0002";
一样的结果
+--------------+-----------+--------------+-----------------+--------------+
| 课程编号 | 总成绩 | 平均成绩 | 成绩总份数 | 学生人数 |
+--------------+-----------+--------------+-----------------+--------------+
| 0002 | 230 | 76.6667 | 3 | 3 |
+--------------+-----------+--------------+-----------------+--------------+
1 row in set (0.00 sec)
我感觉我每天都是在干这类似的 筛选字段, 分组聚合的活. 原本我以为会了 Pandas 就无所畏惧, 为所欲为, 结果, 工作中更多是要去从数据库中查询数据 用sql 的方式来查询返回, 而非用 Python 来搞, 我感觉 Python 我搞得更多的是一些线下的表格数据, 什么 Excel, csv, json... 无敌强, 但更多还是用 sql 来查询数据会更通用和专业些.
需求 02
查询 所有课程成绩小于 90 分 的学生学号, 姓名
分析
先用学号进行 group by (结合 where 成绩 < 90) 的课程数量;
然后再统计, 该学号总共选了几门课, 这样一比较就好啦.
我还是先自己肉眼给看一眼:
select
s_id as "学号",
c_id as "课程号",
score as "成绩"
from score
group by s_id, c_id;
+--------+-----------+--------+
| 学号 | 课程号 | 成绩 |
+--------+-----------+--------+
| 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)
这样一看, 都是满足的呀.
-- 首先呢, 先看看每个人成绩小于 90 分的 课有几门
select
s_id as "学号",
count(c_id) as "小于90的课数"
from score
where score < 90
group by s_id;
+--------+-------------------+
| 学号 | 小于90的课数 |
+--------+-------------------+
| 0001 | 1 |
| 0002 | 2 |
| 0003 | 3 |
+--------+-------------------+
3 rows in set (0.00 sec)
-- 然后呢, 再看看每个人一个选课几门课
select
s_id as "学号",
count(c_id) as "选课数"
from score
group by s_id;
+--------+-----------+
| 学号 | 选课数 |
+--------+-----------+
| 0001 | 3 |
| 0002 | 2 |
| 0003 | 3 |
+--------+-----------+
3 rows in set (0.00 sec)
再将这两个表一拼 inner join 不就美滋滋.. 即 inner 上的学号就是不满足条件的呀
select
a.*,
b.*
from
(
select
s_id as "学号",
count(c_id) as "小于90的课数"
from score
where score < 90
group by s_id) as a
inner join
(
select
s_id as "学号",
count(c_id) as "选课数"
from score
group by s_id) as b
on a.学号= b.学号;
+--------+-------------------+--------+-----------+
| 学号 | 小于90的课数 | 学号 | 选课数 |
+--------+-------------------+--------+-----------+
| 0001 | 1 | 0001 | 3 |
| 0002 | 2 | 0002 | 2 |
| 0003 | 3 | 0003 | 3 |
+--------+-------------------+--------+-----------+
3 rows in set (0.00 sec)
最后来个完整的. 我一般是从里到外的. 不断 select , 面向过程多一些.
select
s_id as "学号",
s_name as "姓名"
from student
where s_id in (
select
a.学号
from
(
select
s_id as "学号",
count(c_id) as "小于90的课数"
from score
where score < 90
group by s_id) as a
inner join
(
select
s_id as "学号",
count(c_id) as "选课数"
from score
group by s_id) as b
on a.学号= b.学号
);
+--------+-----------+
| 学号 | 姓名 |
+--------+-----------+
| 0001 | 王二 |
| 0002 | 星落 |
| 0003 | 胡小适 |
+--------+-----------+
3 rows in set (0.00 sec)
小结
- 聚合函数练习 sum, avg, count + distinct ....这些常见聚合函数的熟练使用呀.
- group by 前的 select 不要放跟 其无关的非聚合字段, 没有意义, where 要置前, 组内过滤用 having
- 复杂查询先理清楚逻辑, 一点点给查出来, 再拼接 Join 再过滤, 子查询等操作, 跟写代码一样的其实
SQL 强化练习 (五)的更多相关文章
- SQL总结(五)存储过程
SQL总结(五)存储过程 概念 存储过程(Stored Procedure):已预编译为一个可执行过程的一个或多个SQL语句. 创建存储过程语法 CREATE proc | procedure pro ...
- 漏洞重温之sql注入(五)
漏洞重温之sql注入(五) sqli-labs通关之旅 填坑来了! Less-17 首先,17关,我们先查看一下页面,发现网页正中间是一个登录框. 显然,该关卡的注入应该为post型. 直接查看源码. ...
- SQL强化(一)保险业务
保险业务 : 表结构 : sql语句 : /*1. 根据投保人电话查询出投保人 姓名 身份证号 所有保单 编号 险种 缴费类型*/SELECTt2.cust_name,t2.idcard,t4.pro ...
- SQL学习笔记五之MySQL索引原理与慢查询优化
阅读目录 一 介绍 二 索引的原理 三 索引的数据结构 四 聚集索引与辅助索引 五 MySQL索引管理 六 测试索引 七 正确使用索引 八 联合索引与覆盖索引 九 查询优化神器-explain 十 慢 ...
- VFP检测SQL Server的五个实例代码
** 需要指出的是,无论下面哪种方式的代码,都需要打开本机的网络共享,否则找不到SQL服务器** 例一 ************************************************ ...
- SQL 实战(五)
一. 将所有to_date为9999-01-01的全部更新为NULL,且 from_date更新为2001-01-01.CREATE TABLE IF NOT EXISTS titles_test ( ...
- sql编程篇 (五) 事务
计算机中的事务 编辑 概念 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用 ...
- 防止 jsp被sql注入的五种方法
一.SQL注入简介 SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库. 二.SQL注入攻击的总体 ...
- SQL入门经典(五) 之键和约束
这一篇博客主要讲键的创建,约束的创建.修改对象和删除对象. 主键:主键是每行的唯一标识符,必须包含唯一值(因此不能为NULL).由于主键在关系中数据库的重要性,因此它是所有键和约束中最重要的.一个表最 ...
- SQL笔记-第五章,函数
一.数学函数 功能 函数名 用法 绝对值 ABS() 指数 POWER() POWER(FWeight,-0.5) 平方根 SQRT() 求随机数 RAND() 舍入到最 ...
随机推荐
- 搭建本地NCBI病毒库用于Blast
搭建本地NCBI病毒库用于Blast 目的:为了通过Blast剔除我数据集中所有与Human任意片段相似度超过97%的序列 日期:2022/11/17 1. Nt库下载 创建conda环境 conda ...
- Springboot 在项目启动时将数据缓存到全局变量
有写字典数据不会频繁更新,但是会频繁查询,想要减少数据库链接次数,把内容缓存到项目的全局变量中,提高方法查询速度 import javax.annotation.PostConstruct; impo ...
- 试试使用 Vitest 进行测试,确实可以减少bug
vitest的简单介绍 Vitest 是一个基于 Vite 的单元测试框架,专为现代前端项目设计. 它结合了 Vite 的高性能和 Jest 的易用性, 提供了开箱即用的 TypeScript.ESM ...
- 【Ryan】: linux下安装ftp
在 Linux 系统下安装 FTP 服务器可以使用多种软件,其中最常见的是 vsftpd(Very Secure FTP Daemon)和 ProFTPD(Professional FTP Daemo ...
- 【ABAQUS2023-Output Vars】使用记录
计算结构的应变能,ALLSE=所有单元的ESEDEN*EVOL.但这不适用于模态分析,因为模态分析EVOL不能用 ALLSE Field: no History: yes .fil: automati ...
- 【MATLAB习题】曲柄滑块机构运动学分析
曲柄滑块机构分享 1. 机构简图 2. 实例 3. matlab code function main %输入已知数据 clear; i1=100; i2=300; e=0; hd = pi/180; ...
- Windows和Ubuntu间TCP连接测试
起因是想在Ubuntu上用Synergy,但是发现爱你怎么都连不上.鼓捣了半天发现似乎Ubuntu监听,Windows测试TCP连接总是不成功,反之却能成功,大概问题就在这,尚未解决先记录一下. 基本 ...
- 探秘Transformer系列之(12)--- 多头自注意力
探秘Transformer系列之(12)--- 多头自注意力 目录 探秘Transformer系列之(12)--- 多头自注意力 0x00 概述 0x01 研究背景 1.1 问题 1.2 根源 1.3 ...
- Laravel11 从0开发 Swoole-Reverb 扩展包(三) - reverb广播驱动使用流程
前情提要 我们第一节的时候,已经大致介绍reverb,他 是 Laravel 应用程序的第一方 WebSocket 服务器,可将客户端和服务器之间的实时通信直接带到您的指尖.开源且只需一个 Artis ...
- mysql 表的创建,修改,删除
查看数据库所有表 show tables 创建 create table 表名 ( 列名 类型 约束条件 ... ) 类型有整形: tinyint(1B) ,smallint(2B),mediumin ...