SQL 强化练习 (十一)
sql 冲冲冲....
也没啥可犹豫, 作为一名数据分析师, 必须掌握的技能, 就要熟练到写 Python 那样的感觉, 就应该可以了, 但目前还是差的比较远, 原因是, 没有相关的一些比较复杂一些的接触, 日常用的 sql 就相关简单, 字段筛选, 表连接, 分组聚合... 虽然都能写出来, 但总是不够自信的. 因此才经常从网上搬砖, 来练习 sql. 这一系列虽然都是关于咱最熟悉的 学生表, 选课表, 教师表 .. 之类的. 但真实业务中也是差不多的, 只是表变得更多和逻辑关系更复杂一些而已. 继续练习吧, 这种东西就是熟能生巧.
表关系

需求 01
查询不同老师, 所教不同课程平均分从高到低显示
分析
分别以, 课程, 老师的视角, 来处理平均分
首先呢, 先从 课程 的视角来做 group by , 看看不同课程的平均分.
select
sc.c_id,
c.c_name,
avg(sc.score) as avg_score
from score as sc
-- 课程名称
inner join course as c
on sc.c_id = c.c_id
group by sc.c_id
-- 降序
order by avg_score desc
+------+--------+-----------+
| c_id | c_name | avg_score |
+------+--------+-----------+
| 0003 | 英语 | 86.3333 |
| 0001 | 语文 | 80.0000 |
| 0002 | 数学 | 76.6667 |
+------+--------+-----------+
3 rows in set (0.00 sec)
蛮简单的, 即根据课程编号分组, 平均成绩做聚合, inner 上课程名称, 最后降序排列即可.
第二种理解, 是以 教师 来做 group by , 来求平均分.
select
t.t_id,
t.t_name,
avg(sc.score) as avg_score
from score as sc
inner join course as c
on sc.c_id = c.c_id
-- 再关联 teacher -> t_name
inner join teacher as t
on c.t_id = t.t_id
group by t.t_id, t.t_name
order by avg_score desc
+------+--------+-----------+
| t_id | t_name | avg_score |
+------+--------+-----------+
| 0003 | NULL | 86.3333 |
| 0002 | 仲尼 | 80.0000 |
| 0001 | 欧拉 | 76.6667 |
+------+--------+-----------+
3 rows in set (0.00 sec)
需求 02
使用分段 [100-85), [85-70), [70-60), [<60) 来统计各科成绩. 分别统计个分数段的人数, 课程id, 课程名称.
分析
先看看基本会涉及的 score 和 course 表, 关联起来
select
c.c_id,
c.c_name
from score as sc
inner join course as c
on sc.c_id = c.c_id
group by c.c_id, c.c_name
+------+--------+
| c_id | c_name |
+------+--------+
| 0001 | 语文 |
| 0002 | 数学 |
| 0003 | 英语 |
+------+--------+
3 rows in set (0.00 sec)
然后来进行分段统计啦, 要进行判断, 肯定是要用到 case when ... 来操作的.
select
c.c_id,
c.c_name,
-- 分组统计
sum(case when sc.score <= 100 and sc.score > 85 then 1 else 0 end) "100-85",
-- 计数用 count 更直观
count(case when sc.score <= 85 and sc.score > 70 then 1 else null end) "85-70",
sum(case when sc.score <= 70 and sc.score >= 60 then 1 else 0 end) "70-60",
count(case when sc.score < 60 then 1 else null end) "< 60"
from score as sc
inner join course as c
on sc.c_id = c.c_id
group by c.c_id, c.c_name
+------+--------+--------+-------+-------+------+
| c_id | c_name | 100-85 | 85-70 | 70-60 | < 60 |
+------+--------+--------+-------+-------+------+
| 0001 | 语文 | 0 | 2 | 0 | 0 |
| 0002 | 数学 | 1 | 1 | 1 | 0 |
| 0003 | 英语 | 1 | 2 | 0 | 0 |
+------+--------+--------+-------+-------+------+
3 rows in set (0.00 sec)
因此, 这里的技巧呢, 还是用了 case when 的用法, 外面再套一个聚合函数. 理解 sum 和 count 都能够实现这个 条件分组和统计的功能. 这个就看自己喜好了. 我个人还是喜欢用 sum 一点, 虽然 count 比较更直观, 这可能是跟我之前用 Tableau 的关系, 它默认的聚合字段就是 sum 嘛, 习惯了. 其实都行的.
也写了挺多的sql练习了, 总体的感觉是, 首先, 是要理清楚它需要哪些字段的参与, 以及多表关联的 key, 当不知道该怎么做的时候, 不妨将其拼接 join 起来, 再一步步查询; 然后就是理解 sql 的执行顺序, 先执行 from , 然后是 where, 在是 group by ... having .... 后面才到 select 因此, 我们在写 sql 的时候, 可以将自己当做 "机器" , 先写 from .. join ... where .. group by .. 最后才写 select , order by .. 这些. 这个思路非常关键,我觉得.
小结
- group by 要非常熟练使用, 就只要涉及聚合, 就要用, 注意 select 字段必须在 group by 中
- 条件求和, 用 case when .. 做一个标记值, 再在外面套一个 sum 或 count 都可以
- 根据 sql 执行顺序来写SQL,这样其实更能加深理解, from > where > group by > having > select ...
SQL 强化练习 (十一)的更多相关文章
- 【转载】 强化学习(十一) Prioritized Replay DQN
原文地址: https://www.cnblogs.com/pinard/p/9797695.html ------------------------------------------------ ...
- SQL强化(一)保险业务
保险业务 : 表结构 : sql语句 : /*1. 根据投保人电话查询出投保人 姓名 身份证号 所有保单 编号 险种 缴费类型*/SELECTt2.cust_name,t2.idcard,t4.pro ...
- 强化学习(十一) Prioritized Replay DQN
在强化学习(十)Double DQN (DDQN)中,我们讲到了DDQN使用两个Q网络,用当前Q网络计算最大Q值对应的动作,用目标Q网络计算这个最大动作对应的目标Q值,进而消除贪婪法带来的偏差.今天我 ...
- SQL强化练习(面试与学习必备)
一.经典选课题A 1.1.请同时使用GUI手动与SQL指令的形式创建数据库.表并添加数据. 题目:设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教 ...
- SQL语句(十一)函数查询
(十一)函数查询 1. 聚合函数 对一组值进行计算,得到一个返回值 SUM(), 求和 AVG(), 求平均 MIN(), 求最小 MAX(), 求最大 COUNT(), 计数,即个数 --例1 求所 ...
- SQL系列(十一)—— 函数(function)
SQL中的函数也非常多,而且不同的DBMS提供了相应的特殊函数.但是常用的共性函数大致可以分为以下几种: 函数类型 函数 数值函数 1.算术计算:+.-.*./ 2.数值处理:ABS()绝对值处理.P ...
- SQL强化(三) 自定义函数
---恢复内容开始--- Oracle中我们可以通过自定义函数去做一些逻辑判断,这样可以减少查询语句,提高开发效率 create -- 创建自定义函数 or replace -- 有同名函数就替换, ...
- SQL强化(二) 在Oracle 中写代码
一 : 关于查询中的转换 -- 字符串转换 一 : decode 函数 转换 SELECT DECODE ( PROTYPE.PRO_TYPE_DATE, 'L', '长', 'm', '短', ' ...
- sql sever基本语法总结
一.数据库导入表 1.先用sql语句创建相应的表,包括表的字段和字段类型 2.导入数据,选择相应的表名,不带'$'符号的表名 二.创建数据库 create datatable 数据库名 三.查看表里的 ...
- 强化学习(十二) Dueling DQN
在强化学习(十一) Prioritized Replay DQN中,我们讨论了对DQN的经验回放池按权重采样来优化DQN算法的方法,本文讨论另一种优化方法,Dueling DQN.本章内容主要参考了I ...
随机推荐
- ((GPIO_TypeDef ) GPIOB_BASE)或((GPIO_TypeDef ) xxxx)
///////////////((GPIO_TypeDef ) GPIOB_BASE)或((GPIO_TypeDef ) xxxx)//////////////////// #define GPIOA ...
- C# List应用 Lambda 表达式
参考链接 : https://blog.csdn.net/wori/article/details/113144580 首先 => 翻译为{ } 然后没有然后 主要基于我工作中常用的几种情况,写 ...
- pnpm : 无法加载文件 \AppData\Roaming\npm\pnpm.ps1,因为在此系统上禁止运行脚本。
1. 安装pnpm npm install -g pnpm #安装 pnpm pnpm --version #查看pnpm版本 安装完成后查看版本时报错 pnpm : 无法加载文件 C:\Users\ ...
- Python 潮流周刊#91:Python 在浏览器中的未来(摘要)
本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...
- Ubuntu修改密码和用户名
Ubuntu是一个Linux操作系统,修改密码和用户名是有危险的动作,请谨慎修改. 一.Ubuntu修改密码和用户名 Ubuntu更改密码步骤:1.进入Ubuntu,打开一个终端,输入 sudo su ...
- Caused by: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String 解决办法
使用MyBatis 更新数据库数据的时候 遇到了这个错误: Caused by: java.lang.IllegalArgumentException: invalid comparison: jav ...
- Netty基础—2.网络编程基础二
大纲 1.网络编程简介 2.BIO网络编程 3.AIO网络编程 4.NIO网络编程之Buffer 5.NIO网络编程之实战 6.NIO网络编程之Reactor模式 1.网络编程简介 既然是通信,那么肯 ...
- 什么!你还不会写Vue组件,编写《功能级权限》匹配公式组件
说明 该文章是属于OverallAuth2.0系列文章,每周更新一篇该系列文章(从0到1完成系统开发). 该系统文章,我会尽量说的非常详细,做到不管新手.老手都能看懂. 说明:OverallAuth2 ...
- 用Docker Swarm实现容器服务高可用
背景与技术选择 根据我之前的几篇「Django 系列」文章,后端架构中我使用了 Django + Celery + RabbitMQ 三个框架/服务.现在有几个问题: 如何用容器快速部署这三个应用? ...
- 原子指令,自旋锁,CAS
原子指令,自旋锁,CAS 问题 我们先看一下这段代码: /* * badcnt.c - An improperly synchronized counter program */ /* $begin ...