sql 强化练习 (七)

继续 sql 练习, 不能停下来的哦, 通过这一系列的搬砖操作, 相信在日常业务的sql 应该是能达到相对清楚地写出来的, 尤其是我做数据分析这块, 感觉真的每天都要写才行, 之前都是用 Python 来轻松搞定, 但仔细一想, sql 才是最通用的哦, sql 熟练了, 我感觉, 数据分析的基础工作就已经完成一半了, 剩下的指标计算, 这些不就是简单的 加减乘除而已, 分分钟脚本批量处理它.

表关系

需求

查询 和 0001 号同学, 所学课程 完全相同的 其他同学的学号.

分析

  1. 先查出 0001 这个兄弟, 的所有课程 id;
  2. 然后查出 not in 这些 课程 id 的这些 学号;
  3. 还要完全相同, 则, group by s_id 后, 选课的数量还必须一致哦.
  4. 从 3 中 排除掉 2 中的 id 剩下的就是满足条件的啦
-- 1. 先看看 0001 这个兄弟选了哪些课程
select c_id from score where s_id = ‘0001‘;
+------+
| c_id |
+------+
| 0001 |
| 0002 |
| 0003 |
+------+
3 rows in set (0.01 sec)

都给选上了. 即下一步, 要找的学生, 必须都同时选了 1,2,3号课程, 注意不能多哦 , 要完全相同.

-- 2. 反向来看, 没有跟 0001 兄弟选课一样的那些人是谁

select s_id 

from score
where c_id not in (
  select c_id from score where s_id = ‘0001‘
);

Empty set (0.00 sec)

空的哦, 还行的.

-- 4. 把那些选课数量 跟 0001 相同的 兄弟给找出来.
select
  s_id
from score
where s_id != "0001"
group by s_id having
  -- 数量一致的兄弟
  count(distinct c_id) = (select count(distinct c_id) from score
  where s_id = "0001")

+------+
| s_id |
+------+
| 0003 |
+------+
1 row in set (0.00 sec)

最后是,从选课数量相同的那些学号中, 过滤掉, 没有选课一样的 那些 id , 剩下的就是呀.

select
  s_id as "学号",
  s_name as "姓名"
from student where s_id in (

  select
    s_id
  from score
  where s_id != "0001"
  group by s_id having
    count(distinct c_id) = (select count(distinct c_id) from score
    where s_id = "0001")
  )

and s_id not in (

select s_id 

from score
where c_id not in (
  select c_id from score where s_id = ‘0001‘
  )
);
+--------+-----------+
| 学号   | 姓名      |
+--------+-----------+
| 0003   | 胡小适    |
+--------+-----------+
1 row in set (0.01 sec)

感觉写起来有点绕, 不过逻辑还是蛮清楚的哦. 感觉还是要重新来复盘一波的.

首先呢, step 1 可以轻易查到, 0001 这个兄弟 选了 1,2,3 门课程.

于是 step2 先选出, 所学课 不在 (not in) (1,2,3) 的同学的学号, 这些事必须要排除的哦.

在来 step3 基于 step2 所剩下的同学, 必然是选了 1, 2,3 中的 某几门 课程, 究竟选了几门, 则判断其课程总数 跟 001 这个兄弟的课程数是相等的 学号即可.

关键就是这个 in 和 not in 的用法, 这个题的逻辑还是, 有点东西的我感觉.

小结

  • 总体问题进行拆解, 分块查询出结果, 跟咱写代码框架是一样的哦.
  • 应用反向思维, in 和 not in 的配合使用
  • 子查询, 查询集的逻辑理清楚, 小 tips 就是 取别名和加括号来区分, 同时注意排版哦.

原文地址:https://www.cnblogs.com/chenjieyouge/p/12638699.html

时间: 2024-10-25 04:08:13

sql 强化练习 (七)的相关文章

SQL总结(七)查询实战

SQL总结(七)查询实战 一.场景 给定一个场景,学生选课系统为例,大家很熟悉. 主要关系: 学生(学号.姓名.年龄.性别) 教师(教师ID,教师姓名) 课程(课程ID,课程名称,任教教师ID) 成绩(学生ID,课程ID,成绩) 二.创建表并预置数据 创建关系表: --学生:Student(SID,SName,SAge,SSex) --学生表(学号.姓名.年龄.性别) --性别,0表示男,1表示女 -- --IF EXISTS(SELECT OBJECT_ID('Student')) /*此处永

C#连接SQL数据库的七个步骤

C#连接SQL数据库还需要进行验证,Windows验证就是SqlServer服务器使用Windows自带的验证系统.在建立数据库连接时,还需要考虑到地址的有效性. C#连接SQL数据库的七个步骤: 1.建立SqlConnection对象: 2.指定SqlConnection对象的ConnectionString 属性: 3.打开数据库连接: 4.指定SQL语句: 5.建立SqlDataAdapter对象和DataSet对象(myDataAdapter = new SqlDataAdapter(s

SQL强化练习

SQL语句强化练习题及答案 一.简单查询 1.列出全部学生的信息. SELECT * FROM 学生 2.列出软件专业全部学生的学号及姓名. SELECT 学号,姓名 FROM 学生 WHERE 专业="软件" 3.列出所有必修课的课号. SELECT DISTINCT 课号 FROM 必修课 4.求1号课成绩大于80分的学生的学号及成绩,并按成绩由高到低列出. SELECT 学号,成绩 FROM 选课 WHERE 课号="1" AND 成绩>80 ORDER

只显示前几条数据的sql语句写法 七种数据库中Select Top的使用方法

七种数据库中Select Top的使用方法 1. Oracle数据库 SELECT * FROM TABLENAME WHERE ROWNUM <= N 2. Infomix数据库 SELECT FIRST N * FROM TABLENAME 3. DB2数据库 SELECT * FROM (SELECT * ROW_NUMBER() OVER({ORDER BY COL1 DESC}) AS ROWNUM FROM TABLENAME) WHERE ROWNUM <= N 或者 SELEC

SQL入门经典(七) 之脚本和批处理

什么是脚本.我们前面学的CREATE TABLE <table name> ,USE <database name>这些都是脚本,为什么用脚本.脚本存储到文件中并且可以重复利用和提取的文件. 创建变量: DECLARE语句最常用的语法: DECLARE @<variable name> <variable type>[=value][[,@<variable name> <variable type>[=value]@<vari

ORACLE PL/SQL练习(七)

PL/SQL变量的作用域,在当前块内部有效. declare v_num number(5,2) := 1.23; begin declare v_num char(10); begin v_num := 12345; dbms_output.put_line(v_num); end; dbms_output.put_line(v_num); end; SQL> declare 2   v_num number(5,2) := 1.23; 3  begin 4     declare v_num

SQL笔记-第七章,表连接

SQL中使用JOIN 关键字来使用表连接.表连接有多种不同的类型,被主流数据库系统支持的有交叉连接(CROSS JOIN).内连接(INNER JOIN).外连接(OUTTER JOIN),另外在有的数据库系统中还支持联合连接(UNION JOIN). 一.内连接(INNER JOIN) SELECT FNumber,FPriceFROM T_Order INNER JOIN T_CustomerON FCustomerId= T_Customer.FIdWHERE T_Customer.FNa

SQL强化(一)保险业务

保险业务 : 表结构 : sql语句 : /*1. 根据投保人电话查询出投保人 姓名 身份证号 所有保单 编号 险种 缴费类型*/SELECTt2.cust_name,t2.idcard,t4.pro_id,t5.pay_type_name,t6.protype_nameFROMcontact t1, -- 联系表customer t2, -- 客户表holder t3, --product t4,pay_type t5,protype t6WHEREt1.contact_text = '159

SQL强化

保险业务 : 表结构 : sql语句 : /*1. 根据投保人电话查询出 投保人 姓名 身份证号 所有保单 编号 险种 缴费类型*/SELECT t2.cust_name, t2.idcard, t4.pro_id, t5.pay_type_name, t6.protype_nameFROM contact t1, -- 联系表 customer t2, -- 客户表 holder t3, -- product t4, pay_type t5, protype t6WHERE t1.contac