UNION 集合运算符正在强制执行“使用文件排序”操作来识别和删除重复项。
UNION ALL 集合运算符将连接两个结果集,而不调用排序操作来识别和删除重复项。
但如果只是将UNION 替换为UNION ALL,我们将依赖于无法保证的行为。如果我们需要按特定顺序返回的结果,那么最外面的查询应该有一个ORDER BY 子句。
https://dev.mysql.com/doc/refman/8.0/en/union.html
摘录
但是,将ORDER BY 用于单个SELECT 语句并不意味着行在最终结果中出现的顺序,因为UNION 默认会生成一组无序的行。
...
(如果有人向其中一个表添加一列,这将导致此查询失败,返回的列数不匹配。)
(第二个 SELECT 中对 teacher.status 的引用无效。)
(就我个人而言,我会在每个集合中添加一个鉴别器列,然后在外部查询的 ORDER BY 子句中引用它。我还会在 SELECT 列表中放弃 * 并指定要为返回。)
我会用这样的方式达到指定的结果:
(
SELECT 'teacher' AS src
, t.fee
, t.fi
, t.fo
, t.fum
FROM `Teacher` t
WHERE t.`status` = 1
)
UNION ALL
(
SELECT 'mission' AS src
, m.one
, m.two
, m.buckle
, m.myshoe
FROM `bouhun`.`missions` m
WHERE m.`status` = 0
)
ORDER
BY src DESC
, CASE src WHEN 'teacher' THEN created_at END DESC
, CASE src WHEN 'mission' THEN RAND() END
* 跟进 *
问题已被编辑,以更改第二个 SELECT 中的表名,使其现在与第一个 SELECT 中引用的表相同。
有了这个更改,我将只使用一个 SELECT。
并避免UNION / UNION ALL 两组。
我们可以在ORDER BY 子句中添加一些巧妙的表达式。
类似这样的:
SELECT t.*
FROM `Teacher` t
WHERE t.status IN (0,1)
ORDER
BY t.status DESC
, IF( t.status=0 , t.created_at , NULL) DESC
, IF( t.status=1 , RAND() , NULL) DESC