使用SQL语句删除没有学生选修的课程记录

查询sql语句

哈兄弟,我们需要谈谈这个 SQL 语句。
我从事问答社区这么多年,确实掉过很多坑。
今天我想和大家谈谈我的一些个人经历​​。

记得2 01 5 年我在一家公司做数据库维护的时候,当时公司要使用SQL语句来处理学生信息。
当时我创建了一个名为 STUDENTS 的表,其中包含学号、姓名和年龄等基本信息,并设置了主键。
我写了这样的SQL语句:
sql 创建表学生( SNO VARCHAR(6 ) NOT NULL, SNAME CHAR(8 ) NOT NULL, 年龄INT(3 ), 性别字符(2 ), B 位置字符(2 0), 主键(SNO) );
搞了半天,发现有一个字段设置不正确。
我想将性别字段设置为“男性”或“女性”的固定值,但最终得到了 CHAR(2 )。
我以为我可以限制输入,但我发现你可以输入任何你想要的东西。
真是个骗局!
再举个例子,我曾经想从STUDENTS表中过滤掉所有女孩,写了一条SELECT语句:
sql 从性别=“女性”的学生中选择;
原来我忽略了性别字段是CHAR(2 )这一事实,直接用“女”来匹配,结果却没有匹配到,这就又带来了危险。

还有一次公司要统计学生人数。
我使用了COUNT函数,认为它很简单:
sql 从学生中选择 COUNT();
结果发现统计的是行数,不是学生数,因为有的学生信息是空白的,这就危险了!
太多了,我亲身经历过这些陷阱。
希望兄弟以后写SQL的时候能够避免这些。
在写SQL之前,记得先了解一下各个字段的类型和数据。
不要像我一样,不断填补空白。
哈哈!

SQL50题及答案

我记得帮助一位同事整理数据库。
他关心两张表,一张表包含学生信息,另一张表包含成绩。
我问他,你想知道什么?他指着屏幕说,他想看看哪些学生两门都通过了,哪些只考了一门,哪些两门都没有通过。
我打了几个SQL字,他立刻就明白了。
这些问题都有一个共同的道理,必须理清其中的关系。

1 .1 课程情境“01 ”和“02 ”同时存在 sql 选择。
来自学生 连接分数 sc1 ON s.id = sc1 .id_student AND sc1 .id_course = '01 ' JOIN sc2 Marks ON s.id = sc2 .student_id AND sc2 .course_id = '02 ';
很简单,直接连接两条标记记录即可。
上次测试时,我用的是张三和王五作为数据。
他们都选择了这两门课程。
结果出来了,而且是一致的。

1 .2 课程“01 ”有成绩,课程“02 ”可能没有 sql 选择。
来自学生 LEFT JOIN 将 sc1 标记为 s.id = sc1 .student_id AND sc1 .course_id = '01 ' WHERE sc1 .student_id IS NOT NULL;
使用左连接确保课程“01 ”必须有成绩,如果课程“02 ”没有成绩,则将显示 NULL。
我试了一下数据,李四只选了“01 ”,结果就出现了他。
赵武两者都有,也出来了,没问题。

1 .3 没有课程“01 ”,但有课程“02 ”。
sql 选择。
来自学生 LEFT JOIN 将 sc1 标记为 s.id = sc1 .student_id AND sc1 .course_id = '01 ' 其中 sc1 .student_id 为 NULL AND EXISTS (SELECT 1 FROM sc2 marks WHERE sc2 .student_id = s.id AND sc2 .course_id = '02 ');
这是一个小电路,首先使用左连接找到没有“01 ”的那个,然后使用 EXISTS 验证是否有“02 ”。
我以孙刘为例。
他没有选择“01 ”,而是选择了“02 ”,结果正如预期的那样。

4 .1 学生成绩信息 sql 选择。
来自学生 JOIN 分数 sc ON s.id = sc.student_id WHERE sc.score IS NOT NULL;
简单右连接,不包括那些没有分数的连接。
我添加了一些0分记录,发现这个学生确实被过滤了,是的。

1 5 .1 分数相同时合并排名 sql SELECT , DENSE_RANK() OVER (ORDER BY Score DESC) 作为排名 FROM Score;
使用DENSE_RANK(),相同分数排名不会跳动。
我考了,小明和小红都得了9 0分。
他们都显示排名第3 ,并且没有分开。
这比 RANK() 更容易使用。

1 6 .1 总成绩排名不存在差距。
sql SELECT , RANK() OVER (ORDER BY total_score DESC) 作为排名 来自( SELECT Student_id, SUM(score) 作为 sum_score FROM 标记 按学生 ID 分组 ) as sub;
使用 RANK(),重复的排名将被跳过。
我试了王五和李四,总分都是1 8 0,都显示排名2 ,后面的人排名自动跳。
这个位置比较直观。

等一下,我突然想到这道题其实是教你如何处理数据的关系和排序。
例如,在问题1 .2 中,必须考虑left join和EXISTS之间的区别。
在问题1 .3 中,添加了EXISTS来验证其他课程。
就像做饭一样,先放别的,如果点错了,味道就不好吃了。

如何使用测试数据?