1.准备工作
准备了两张表,用于测试
-- ----------------------------
-- Table structure for info
-- ----------------------------
DROP TABLE IF EXISTS `info`;
CREATE TABLE `info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`views` int(255) DEFAULT NULL,
`info_type_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
-- ----------------------------
-- Table structure for info_type
-- ----------------------------
DROP TABLE IF EXISTS `info_type`;
CREATE TABLE `info_type` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
将上面的sql导入navicat
info表
info_type表
2.select语句发生了什么?
现在我要查询info表所有的数据,很容易写出如下sql
SELECT * FROM info;
不知道大家想过没有,select的时候究竟发生了什么?
其实sql语句执行的时候,如果看到select,就会根据from后面的表名,一条一条的查询,最终合并到结果集中。
如果我们再加一个where条件,那么就会进行筛查。
注意,这个筛查会发生在每一条语句上。
比如,当你执行SELECT * from info where info_type_id = 2;这条语句,0.001ms的时候是查询这条数据
请问,他符合where条件吗?不符合吧,那么这一条就过滤掉,继续下一条。
最终,不符合条件的都被过滤,那些符合条件的才被筛出来了。
3.复杂查询
下面介绍一个比较考验思维的sql,非常适合复习我们已有的sql知识。
对于某些复杂的需求,sql的编写难度会加大。
比如,现在我要求查询info_type_id=3,并且浏览量最高的两条数据,考虑下怎么写?
先看下info_type_id=3的所有数据
SELECT * from info where info_type_id = 3;
浏览量最高的两条数据,很容易想到对views进行倒叙排序,然后取前两条。
SELECT * from info where info_type_id = 3 ORDER BY views desc;
那么,怎么取前两条呢?直接分页即可。
SELECT * from info where info_type_id = 3 ORDER BY views desc LIMIT 0,2;
那假如我要用一条sql获取每个类别浏览量最高的前两条呢?
相信很多人第一反应是用group by 去分组,但是似乎比较困难。
其实,我们只要牢记select的原理是一条一条去扫描匹配的,就不难。
比如,我们扫描到第一条:
思考,该怎么去判断这一条的views(浏览量)是该类型(info_type_id=3)前两位呢?
是不是只需要让这张表中info_type_id=3(条件1)并且views大于这条数据的views(条件2),然后再要求这样的数据<=1条(条件3)就行了呢?
说说为什么要求这样的数据<=1条?
如果等于1,说明只有一条比当前这条views大,加上这一条,就是views最高的两条,符合条件。
如果小于1,说明没有任何一条比当前这条views大,那么当前这条就是views最高的那条,符合条件。
于是,针对info_type_id=3的情况,得到sql
select t1.* from info t1 where t1.info_type_id = 3
and (select count(1) from info t2 where t2.info_type_id = 3 and t2.views > t1.views ) <= 1
成功了,然后再改写成全部的情况:
SELECT t1.* from info t1
where (
select count(1) from info t2 where t2.info_type_id = t1.info_type_id
and t2.views > t1.views ) <= 1
order by info_type_id;
总之,我们要牢记一点,select的时候,是一条条去执行的,where条件就是对每一条的过滤。这样的复杂sql也就不难理解了。
我是兔哥,关注我,学习编程不迷路~~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)