SQL 强化练习 (六)
本以为学会了Python 就已经天下无敌, 果然, 我还是太傻太天真了. 业务中几乎就没有用 Python 来直接连接数据库进行操作, 当然我是说数据这块哈. 哎, 难受, 还是用的 sql 这种方式. 但有个问题在于, sql 没有类似于编程语言那样来用个数据结构存储存储中间过程, 于是呢, 在写 "套娃" 就是 sql 嵌套的时候, 可难受了, 一不小心就会写乱, 阅读体验也不好, 但, 又没有其他的办法, 只能去多加练习去适应哦.
表关系
反复练习, 只能这样去提高理解了, 果然是唯手熟尔, 对此我深信不疑.
需求 01
-- 查询 没有学全所有课程的学生学号, 姓名
分析
student 表 left join score 表, 然后在 group by s_id 再 having 选课数量 < 实际有多少门课
-- 先看看总体情况
select
st.*,
sc.*
from student as st
left join score as sc
on st.s_id = sc.s_id
tips: 一定要用 left join 这样才不会漏掉有学生压根就没有选过课的情况
+------+-----------+------------+--------+------+------+-------+
| s_id | s_name | birth_date | gender | s_id | c_id | score |
+------+-----------+------------+--------+------+------+-------+
| 0001 | 王二 | 1989-01-01 | 男 | 0001 | 0001 | 80 |
| 0001 | 王二 | 1989-01-01 | 男 | 0001 | 0002 | 90 |
| 0001 | 王二 | 1989-01-01 | 男 | 0001 | 0003 | 99 |
| 0002 | 星落 | 1990-12-21 | 女 | 0002 | 0002 | 60 |
| 0002 | 星落 | 1990-12-21 | 女 | 0002 | 0003 | 80 |
| 0003 | 胡小适 | 1991-12-21 | 男 | 0003 | 0001 | 80 |
| 0003 | 胡小适 | 1991-12-21 | 男 | 0003 | 0002 | 80 |
| 0003 | 胡小适 | 1991-12-21 | 男 | 0003 | 0003 | 80 |
| 0004 | 油哥 | 1996-10-01 | 男 | NULL | NULL | NULL |
+------+-----------+------------+--------+------+------+-------+
果然, left join 就能把 "油哥" 这个兄弟, 一门课都不选的特例, 也给筛选出来了哦.
然后, "没有选全" , 也就是 group by 学生id, count(课程号) < 总课程数 了呗. 组内筛选用 having.
select
st.*,
sc.*
from student as st
left join score as sc on st.s_id = sc.s_id
group by st.s_id having
count(distinct sc.c_id) < (select count(distinct c_id) from course);
+------+--------+------------+--------+------+------+-------+
| s_id | s_name | birth_date | gender | s_id | c_id | score |
+------+--------+------------+--------+------+------+-------+
| 0002 | 星落 | 1990-12-21 | 女 | 0002 | 0003 | 80 |
| 0004 | 油哥 | 1996-10-01 | 男 | NULL | NULL | NULL |
+------+--------+------------+--------+------+------+-------+
这样不就, 获取到了 s_id 了吗, 然后在外面给套上一层, 就搞定了哦.
select
s_id as "学号",
s_name as "姓名"
from student where s_id in (
select
st.s_id -- 只要学号即可
from student as st
left join score as sc on st.s_id = sc.s_id
group by st.s_id having
count(distinct sc.c_id) < (select count(distinct c_id) from course)
);
+--------+--------+
| 学号 | 姓名 |
+--------+--------+
| 0002 | 星落 |
| 0004 | 油哥 |
+--------+--------+
2 rows in set (0.00 sec)
需求 02
查询 至少有一门课, 与学号为 "0001" 的学生, 所学课程相同, 的学生学号和姓名.
分析
先看 0001 这个老铁选了哪些课, 然后从 score 中查出 选个这个课有哪些学生学号 不就行了嘛
select c_id from score where s_id = "0001";
+------+
| c_id |
+------+
| 0001 |
| 0002 |
| 0003 |
+------+
这个兄弟, 把 1,2,3 号课程都给选上了, 果然是学霸, 目测.
然后再看, score 中 也选择了这些课的学号有哪些.
select
s_id,
c_id
from score
where c_id in (
select c_id from score where s_id = "0001"
);
+------+------+
| s_id | c_id |
+------+------+
| 0001 | 0001 |
| 0003 | 0001 |
| 0001 | 0002 |
| 0002 | 0002 |
| 0003 | 0002 |
| 0001 | 0003 |
| 0002 | 0003 |
| 0003 | 0003 |
+------+------+
8 rows in set (0.00 sec)
这样就把跟 0001 同学有选相关的课程的所有兄弟的, 学号, 课号给 拉出来了. 然后, 需要再对学号进行去重, 同时呢, 还需要将 0001 自己给排除掉哦
select
s_id as "学号",
s_name as "姓名"
from student where s_id in (
select distinct s_id from score
where c_id in (
select c_id from score where s_id = "0001"
)
-- 排除自己
and s_id != "0001"
);
+--------+-----------+
| 学号 | 姓名 |
+--------+-----------+
| 0002 | 星落 |
| 0003 | 胡小适 |
+--------+-----------+
2 rows in set (0.00 sec)
当然, 也可以用 inner join 的方式, 当数据量比较大的时候, 感觉用 join 的方式会更加快一点哦
select
a.s_id as "学号",
a.s_name as "姓名"
from student as a
-- 内连接查出的学号
inner join (
select distinct s_id from score
where c_id in (
select c_id from score where s_id = "0001"
)
-- 排除自己
and s_id != "0001") as b
on a.s_id = b.s_id;
+--------+-----------+
| 学号 | 姓名 |
+--------+-----------+
| 0002 | 星落 |
| 0003 | 胡小适 |
+--------+-----------+
2 rows in set (0.00 sec)
小结
- 灵活应用 join, group by + having 这样的子查询的方式, "面向过程" 写sql, 就是一点点查出来.
- 当考虑数据量的时候, 如果先用的子查询, 在查询效率上, 可能也应多考虑 join 来进行配合使用
- 感觉sql 其实和面向过程的编程是一样的, 查一个表就取个别名, 然后继续查, 拼接, 或者套娃啥的, 感觉熟练了就会好还多的, 还是需要不断练习哦.
SQL 强化练习 (六)的更多相关文章
- SQL总结(六)触发器
SQL总结(六)触发器 概念 触发器是一种特殊类型的存储过程,不由用户直接调用.创建触发器时会对其进行定义,以便在对特定表或列作特定类型的数据修改时执行. 触发器可以查询其他表,而且可以包含复杂的 S ...
- 漏洞重温之sql注入(六)
漏洞重温之sql注入(六) sqli-labs通关之旅 Less-26 进入第26关,首先我们可以从网页的提示看出本关是get型注入. 我们给页面添加上id参数后直接去查看源码. 需要关注的东西我已经 ...
- SQL学习笔记六之MySQL数据备份和pymysql模块
mysql六:数据备份.pymysql模块 阅读目录 一 IDE工具介绍 二 MySQL数据备份 三 pymysql模块 一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测 ...
- SQL入门经典(六) 之视图
视图实际上就是一个存储查询,重点是可以混合和匹配来自基本表(或其他视图)的数据,从而创建在很多方面象另一个普通表那样的起的作用.可以创建一个简单的查询,仅仅从一个表(另一个视图)选择几列或几行,而忽略 ...
- JavaScript强化教程 - 六步实现贪食蛇
1.首先创建div 并且给div加样式 <div id="pannel" style="width: 500px;height: 500px;z-index: 1; ...
- SQL Server(六)——索引、视图和SQL编程
1.索引 添加索引,设计界面,在任何一列前右键--索引/键--点击进入添加某一列为索引 2.视图 视图就是我们查询出来的虚拟表 创建视图:create view 视图名 as SQL查询语句,分组,排 ...
- PL/SQL学习(六)触发器
原文参考:http://plsql-tutorial.com/ 创建语法: CREATE [OR REPLACE ] TRIGGER trigger_name {BEFORE | AFTER | IN ...
- 抓取锁的sql语句-第六次修改
增加异常处理 CREATE OR REPLACE PROCEDURE SOLVE_LOCK AS V_SQL VARCHAR2(3000); --定义 v_sql 接受抓取锁的sql语句V_SQL02 ...
- SQL强化(一)保险业务
保险业务 : 表结构 : sql语句 : /*1. 根据投保人电话查询出投保人 姓名 身份证号 所有保单 编号 险种 缴费类型*/SELECTt2.cust_name,t2.idcard,t4.pro ...
- SQL随记(六)
1.关于dbms_sql包的一些执行语句 cursor_name := DBMS_SQL.OPEN_CURSOR; --打开游标: DBMS_SQL.PARSE(cursor_name, var_dd ...
随机推荐
- 2024电子取证“獬豸杯”WP
简介: 竞赛为个人赛,工具自备,只发证书(还没用,公告这么写的哈)竞赛选手们将对模拟的案件进行电子数据调查取证,全面检验参赛选手电子数据取证的综合素质和能力. 检材链接: https://pan.ba ...
- Week08_day07(DataX从mysql上读取数据传输到HDFS上)
简介DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL.Oracle.HDFS.Hive.OceanBase.HBase.OTS.ODPS 等各种异构数据源之间高效的 ...
- 【论文随笔】多行为序列Transformer推荐(Multi-Behavior Sequential Transformer Recommender)
前言 今天读的论文为一篇于2022年7月发表在第45届国际计算机学会信息检索会议(SIGIR '22)的论文,文章主要为推荐系统领域提供了一个新的视角,特别是在处理用户多行为序列数据方面,提出了一种有 ...
- TypeError: 'NoneType' object is not iterable 一次错误场景
TypeError: 'NoneType' object is not iterable 源码 def get_url(lines): urls=[] for line in lines: if 'i ...
- DCL(Double-checked Locking双重校验锁)实现单例模式的原理、问题与解决方案
好的,要深入理解DCL(Double-Checked Locking)双重校验锁的原理.问题以及解决方法. 首先,我需要回忆一下单例模式的基本概念,因为DCL通常用于实现单例模式. 单例模式确保一 ...
- 最新活动 ISS 国际空间站 MAI-75 SSTV活动计划于2020年8月4日至5日
MAI-75 SSTV活动计划于2020年8月4日和5日举行 8月3日至9日这一周的最后宇航员时间表最近公布了,它显示了定于8月4日和5日进行的MAI-75活动.这是在Space X Demo-2脱 ...
- HTML5 给网站添加图标
1.首先将图标上传到对应的目录下 2.在网页的index.html,添加已下代码到<head>标签里 <link rel="icon" href="i_ ...
- 比较 HashSet、LinkedHashSet 和 TreeSet 三者的异同
比较 HashSet.LinkedHashSet 和 TreeSet 三者的异同HashSet.LinkedHashSet 和 TreeSet 都是 Set 接口的实现类,都能保证元素唯一,并且都不是 ...
- sql 使用with 递归
---前提:有上下级关系的关系表 ---示例:组织架构表 DECLARE @orgId NVARCHAR(20)='0001'; --向下递归,查询@orgId 下的所有结点...包括儿子-孙子节 ...
- Zotero 设置坚果云同步(使用 WebDAV 的方法)
1.坚果云设置 登录坚果云:官网,注册账号 1.建立个人文件夹:zotero 2.在网页打开右上角的 账户信息,并选择 安全选项 在页面下方选择 添加应用 并输入与前面文件夹对应的名称 zotero ...