本文探讨了SQL中子查询的使用,特别是嵌套查询与相关子查询的区别,以及子查询中使用ORDER BY语句的常见问题。在高版本MySQL中,子查询中的排序可能不会生效,文章提供了实例和解决方案,建议将排序操作放在外层主查询中。 摘要生成于 ,由 DeepSeek-R1 满血版支持,

嵌套查询:有(内层)子查询的查询,也就是说,包括 外层主查询 内层子查询 的查询。

(内层)子查询:子查询还可以包括子查询。 子查询 分为 嵌套子查询 相关子查询

嵌套子查询:执行不依赖与外部的查询。一般可以分为:返回单值的子查询 和 返回一个列表的子查询。

例如:select s.*,(select countryName from country where id=1 ) countryName from student s

相关子查询:执行依赖于外层主查询:多数情况下是子查询的where句中引用了外层主查询的表。

例如:select s.*,(select name from user where id=s.id) name from student s 

相关子查询在数据量大的时候要慎用,会大大降低查询速度。
可以把相关子查询的条件去掉先查出来一个所有数据的临时表,这样就只查了一次,不会在每次外层查询时都额外查一次内层查询。
select count(*) from vote where targetID=cv.videoID -->
(select targetID,count(voteNum) voteNum from vote where voteNum=1 and enable=1 group by targetID) as vv

二 子查询排序问题

高版本的MySQL(5.6以上)在子查询中使用order by 语句后查询结果并不会显示排序后的结果。
子查询大多数是作为一个结果给主查询使用,所以子查询不需要排序,当子查询中有order by语句时,数据库会自动优化,即忽略order by语句。
参考:https://www.jianshu.com/p/48452a136875
结论:在SQL标准中,子查询中的order by是不生效的
MySQL 5.7由于在这个点上遵循了SQL标准导致问题暴露,而在MySQL 5.6/8.0中这种写法依然是生效的

三 记录一下遇到的坑

1.单独查 是降序
2. 添加一个where条件 变为无序(可能也有顺序,但我是看不出来)
3.添加2个where条件 变为升序
4.还有更坑的,因为在子查询排了序,在navicat中是降序desc,但是到代码中变成升序asc(目前原因未知,有待考察)
目前这个原因还未找到,有待后续研究。

吸取教训,不要在子查询中排序,不起作用,要把排序放到外层主查询

问题4的原因找到了
是因为在代码中用了activityID用了String类型,而且是#{},相当于在sql中是“1”
但是为什么用不同的类型会导致排序不一样还是不明白

一、问题背景 在我们的考试系统中,用户可以多次考试,然后需要去用户最新的考试记录,而且是需要批量去取多个用户的最新的考试记录或者单个用户的多个最新考试记录,之前写的sql是子查询根据时间排序,然后进行分组取最新的。sql如下: select * from (select * from `user_exam` where uid = 666 and exam_id in (1,2,3) order by create_time des......
大多数子查询不需要排序,没有意义。因为子查询大多数是作为一个结果或参数给主查询使用。但top-n问题除外。举个例子,查询员工表中“行政部”的员工。select * from emp where empdetno = (select empdetno from bmb where bmname = '行政部')子查询的结果给主查...
获取分组后,组内排名第一或最后的数据行。 利用子查询,desc 或者asc,然后GROUP BY 某个维度例如userId, 再select,会默认取分组后的排序的第一条数据。 mysql分组排序取组内第一的数据行 网上都说Mysql5.7,在子查询的ORDER BY子句后面,必须加上LIMIT 10000000,实测不加LIMIT 结果确实会有问题 未加Limit,没有排序效果 加上后跟预期正常
在做项目中遇到一个分组查询并取分组中最新的数据,MySQL查询时按照某个字段进行分组,查询结果默认获取分组中的第一条数据。现在需要进行子查询,也即是现进行对数据的排序再进行分组,但是分组内的排序不起作用。查找了相关资料,说是在MySQL5.6之后,sql执行时会有一个优化,就会把子句中的order by去掉。 sql如下: --子查询排序不起作用 SELECT ANY_VALUE(h.id) id, ANY_VALUE(h.creatorId) creatorId, ANY_VALUE(h.createT
--执行顺序 : from --> where --> select --in (值列表) 判断前面的某个内容的值是否在in()的值列表中,如果在就是满足,如果不在就是不满足 ***** -- 查询工资为 1500, 2000, 2500, 5000的员工的信息 select * from emp where sal = 1500 or sal = ..
#### 添加 `LIMIT` 对于 MySQL 版本 5.7 及以上,子查询中的 `ORDER BY` 需要配合 `LIMIT` 使用才能生效。即使 `LIMIT` 的数值设置得非常大也能解决问题[^1]。 ```sql SELECT type, book_name FROM ( SELECT * FROM book ORDER BY visits_num DESC LIMIT 9999 GROUP BY type; #### 使用派生表并指定列名 另一种方法是在子查询中明确指定需要排序的字段,并在外层查询中继续处理这些数据[^3]。 ```sql SELECT * FROM ( SELECT id, name, visit_count FROM users ORDER BY visit_count DESC ) AS sorted_users; #### 利用变量实现自定义排序 通过引入用户定义变量可以在一定程度上绕过这个问题,适用于某些特定场景下的需求[^4]。 ```sql SELECT * FROM ( SELECT uo.*, @rownum := @rownum + 1 AS rank FROM table_name uo, (SELECT @rownum := 0) r ORDER BY some_column DESC ) ranked_results;