sql 强化练习 (七)

继续 sql 练习, 不能停下来的哦, 通过这一系列的搬砖操作, 相信在日常业务的sql 应该是能达到相对清楚地写出来的, 尤其是我做数据分析这块, 感觉真的每天都要写才行, 之前都是用 Python 来轻松搞定, 但仔细一想, sql 才是最通用的哦, 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 就是 取别名和加括号来区分, 同时注意排版哦.
上一篇:位运算判断一个数是否是奇数


下一篇:初识编码格式