子查询用order by,外层用group by但是order by没生效

发布时间 2023-08-25 18:14:57作者: 曾曾曾zzq

今天遇见一个需求:从entity表查询name在我传过来的一个name集合里面,但是同一个name可能会重复,所以我需要根据plan字段判断取每个name的第一条,如果plan=我传进来的plan,优先,plan不等于我传进来的参数的情况下,如果plan不为空,优先,最后就是plan为空的数据。返回的数据就是每个name的第一条的集合

后面的解决方法是SELECT
*
FROM
(
SELECT
*
FROM
entity
ORDER BY
CASE

WHEN plan = '1' THEN
0 
WHEN plan != '1' 
AND plan IS NOT NULL THEN
1 ELSE 2 

END limit 10
) a
WHERE
NAME in ('zhang','li')
GROUP BY
NAME
但是很奇怪,里面我不加limit,他查出来的数据并不是order by排序后的分组靠前数据,也就是order by没生效。查阅得知:
mysql 5.7版本查询进行优化了,认为子查询中的order by可以进行忽略,只要Derived table里不包含如下条件就可以进行优化:

UNION clause
GROUP BY
DISTINCT
Aggregation
LIMIT or OFFSET
简单来说不想被优化就需要在子查询里添加上面的条件(仅仅是用作不被优化)

所以子查询在用order by,外层用group by的时候,需要加上以上条件,最简单当然也就是limit了

后面觉得这样还是要用limit,觉得不好,limit的值要保证比我数据大,不然也会有问题,后面转换思路,这样解决了
SELECT
e.*
FROM
entity e
WHERE
( CASE WHEN plan = '1' THEN 0 WHEN plan != '1' AND plan IS NOT NULL THEN 1 ELSE 2 END ) = (
SELECT
min( CASE WHEN plan = '1' THEN 0 WHEN plan != '1' AND plan IS NOT NULL THEN 1 ELSE 2 END )
FROM
entity hh
WHERE
hh.NAME = e.NAME
AND e.NAME IN ( 'zhang', 'li' )
)