一条sql搞定这个需求,面试官直呼内行

分类:Java

设想一下这种场景,sql应该怎么写:学生表中保存了学生姓名和课程信息,现在需要把选修课程1和课程2的学生姓名打印出来。或者类似的,在订单表中,把既购买了商品A,也购买了商品B的订单号找出来。粗看起来,这样的需求用sql实现比较简单,在WHERE条件中把课程1和课程2的信息加进去即可,但仔细想想,好像又没那么容易,因为有的学生只选修了课程1(或者课程2),如果用IN这个关键字的话,又把这部分学生的信息查询出来了。

我们用个图来说明一下:

一条sql搞定这个需求,面试官直呼内行

对于上面的数据,需要找出选修了课程id为1和2的学生姓名,显然,满足条件的只有Tom,那这样的sql怎样写呢?我们先把表创建起来,然后插入如上图所示的简单数据:

CREATE TABLE `t_student_course` (
  `id` int(11NOT NULL AUTO_INCREMENT COMMENT '主键',
  `course_id` int(11NOT NULL COMMENT '课程id',
  `stu_name` varchar(32NOT NULL COMMENT '学生姓名',
  PRIMARY KEY (`id`)
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `t_student_course` VALUES ('1''1''Tom');
INSERT INTO `t_student_course` VALUES ('2''2''Tom');
INSERT INTO `t_student_course` VALUES ('3''1''John');
INSERT INTO `t_student_course` VALUES ('4''3''John');
INSERT INTO `t_student_course` VALUES ('5''1''Jerry');

正如上面所说的,如果我们直接在WHERE语句查询course_id等于1和2的数据,并且按照学生姓名分组,那返回的数据就有Tom、John和Jerry,显然是不对的。

SELECT stu_name FROM t_student_course WHERE course_id IN (1,2)
GROUP BY stu_name

我们需要在GROUP BY后面再加上过滤条件,也就是对分组后的数据记录条数是2,此时需要使用关键字HAVING,同时,在实际的数据表中,字段可能远远不这么几个,也可能会存在冗余的情况,所以需要过滤掉字段的重复值。最终的sql如下:

SELECT stu_name FROM t_student_course WHERE course_id IN (1,2)
GROUP BY stu_name
HAVING COUNT(DISTINCT course_id) = 2

执行的结果就是我们想要的答案:Tom.

都看到这里了,请帮忙一键三连啊,也就是点击文末的在看、点赞、分享,这样会让我的文章让更多人看到,也会大大地激励我进行更多的输出,谢谢!

推荐阅读:

MySQL如何进行表之间的关联更新

高频面试题:多线程顺序打印ABC字符20次

一网打尽:MySQL索引失效的场景大搜罗

这个设计模式的用法,一般人我不告诉他

《论语》是很多公司取名的源泉

原文始发于微信公众号(互联网全栈架构):一条sql搞定这个需求,面试官直呼内行

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/173645.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!