跟他学sql(第三天)

前言

好了,今天我们又来学sql。

第十二问

题目:查询和01号同学所学课程完全相同的其他同学的学号。
分析:看到完全相同,我们又想起之前张三老师上过的所有课,同样的这道题我们也采用同样的方式。
先查询出01学生所学过的所有课的c_id,以及课程数count(c_id),然后查询出score表中同样课程好的记录,然后按照学号聚合(group byhaving),聚合之后看这些学生的课程数是否和01同学一致,如果一致说明学的课完全一样。

  • 学号s_id
  • 课程号c_id
  • 课程数count(c_id)

看来这次一张表就能解决,代码如下

//所以要先查询出学过相同课程的s_id,然后判断s_id是否在其中
SELECT s1.s_id id
FROM 
(
	//记得把c_id字段也查出来,这样才能比较
	SELECT s_id,c_id FROM score WHERE c_id
	in 
	(SELECT c_id FROM score WHERE s_id = '01')
) s1
GROUP BY s1.s_id
HAVING 
COUNT(c_id) = (SELECT COUNT(c_id) FROM score WHERE s_id = '01')
--如果要改正确的话在这边加上一句,筛选掉课程数包含且大于01同学的情况
--不过这样太冗余了
--AND COUNT(c_id) = (SELECT COUNT(c_id) FROM score GROUP BY s_id HAVING s_id = id)
AND 
s1.s_id != '01'  

事实证明上面这种写法是有问题的,当02学生的课程包含且大于01学生的课程的时候也会被筛选出来(多谢杰哥指出,杰哥牛逼 )。

正确的写法应该是这样:

SELECT s_id FROM score 
-- 查询出上过和01同学不一样课的学生,剩下的学生上过的课一定包含于01学生
WHERE score.s_id NOT IN(
	SELECT s_id FROM score 
	WHERE c_id NOT IN 
	(SELECT c_id FROM score WHERE s_id = '01')
)
AND s_id != '01'
GROUP BY s_id 
HAVING COUNT(c_id) = 
(SELECT COUNT(c_id) FROM score WHERE s_id = '01')

在这里插入图片描述

第十三问

题目:查询没学过张三老师的任意一门课的学生的姓名。
分析:没学过任意一门,又是not in,先查询出张三老师教过的课,然后查询出学过这些课的学生的s_id,再然后在Student表中not in

  • 老师姓名t_name
  • 学生姓名s_name
  • 课程号c_id
  • 学生学号s_id
SELECT s_name FROM Student WHERE s_id NOT IN
(
	SELECT s_id FROM score 
	WHERE c_id 
	in 
	(
		SELECT c_id FROM course JOIN teacher on course.t_id = teacher.t_id WHERE t_name = '张三'
	)
)

在这里插入图片描述

第十四问

题目:查询两门及以上不及格课程的同学的学号、姓名、平均成绩
分析:

  • 学号s_id
  • 姓名s_name
  • 平均成绩AVG(s_score)

两门以上不及格,我们可以先计算出s_score小于60的记录,然后使用group by聚类,然后使用count(c_id)就能获得有几门课程不及格。

SELECT score.s_id,Student.s_name,AVG(s_score) 
FROM score 
JOIN Student 
on score.s_id = Student.s_id 
WHERE score.s_score < 60 
GROUP BY score.s_id 
HAVING COUNT(score.c_id) > 1

在这里插入图片描述

附加题

题目:查询出总成绩排名前3的同学的学号
分析:这道题是我在今天面经中看到的题目,感觉TOPK的问题还没做到过,所以放到这里实现一下。
一般TOPK的问题都是采用order by排序,然后使用limit字段来进行限制。

SELECT s_id,SUM(s_score) 
FROM score 
GROUP BY s_id 
ORDER BY SUM(s_score) DESC 
//limit 3是指从0开始往后数3个
//如果要查询第二第三名就要使用limit 1,2
//意思是从1开始往后数2个
LIMIT 3

在这里插入图片描述


今天就练习到这里吧,感觉自己的sql操作越来越熟练了呢。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。在编写C程序时,需要注意变量的声明和定义、指针的使用、内存的分配与释放等问题。C语言中常用的数据结构包括: 1. 数组:一种存储同类型数据的结构,可以进行索引访问和修改。 2. 链表:一种存储不同类型数据的结构,每个节点包含数据和指向下一个节点的指针。 3. 栈:一种后进先出(LIFO)的数据结构,可以通过压入(push)和弹出(pop)操作进行数据的存储和取出。 4. 队列:一种先进先出(FIFO)的数据结构,可以通过入队(enqueue)和出队(dequeue)操作进行数据的存储和取出。 5. 树:一种存储具有父子关系的数据结构,可以通过中序遍历、前序遍历和后序遍历等方式进行数据的访问和修改。 6. 图:一种存储具有节点和边关系的数据结构,可以通过广度优先搜索、深度优先搜索等方式进行数据的访问和修改。 这些数据结构在C语言中都有相应的实现方式,可以应用于各种不同的场景。C语言中的各种数据结构都有其优缺点,下面列举一些常见的数据结构的优缺点: 数组: 优点:访问和修改元素的速度非常快,适用于需要频繁读取和修改数据的场合。 缺点:数组的长度是固定的,不适合存储大小不固定的动态数据,另外数组在内存中是连续分配的,当数组较大时可能会导致内存碎片化。 链表: 优点:可以方便地插入和删除元素,适用于需要频繁插入和删除数据的场合。 缺点:访问和修改元素的速度相对较慢,因为需要遍历链表找到指定的节点。 栈: 优点:后进先出(LIFO)的特性使得栈在处理递归和括号匹配等问题时非常方便。 缺点:栈的空间有限,当数据量较大时可能会导致栈溢出。 队列: 优点:先进先出(FIFO)的特性使得

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值