使用“Union distinct”构造时保留子查询中的记录顺序

use*_*692 1 mysql union sql-order-by

我想确保在使用 Union distinct 时保留子查询结果的顺序。请注意,在进行联合时,需要“union distinct”来过滤重复项。

例如:

select columnA1, columnA2 from tableA order by [columnA3] asc
union distinct
select columnB1, columnB2 from tableB
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我期望从子查询( select columnA1columnA2from tableAsort by [columnA3]asc)排序的记录首先出现(按asc排序返回columnA3),然后是来自tableB.

我假设我不能添加另一个虚拟列,因为这会使 union 不同而不起作用。所以,这行不通:

select column1, column2 from 
 ( select column1, column2, 1 as ORD from tableA order by [columnA3] asc
 union distinct
 select column1, column2, 2 as ORD from tableB 
 ) order by ORD
Run Code Online (Sandbox Code Playgroud)

use*_*692 5

本质上,MySQL 在使用“Union distinct”构造时不会保留来自子查询的记录顺序。经过一番研究,我发现如果我们放入限制子句或嵌套查询,它就可以工作。所以,下面是两种方法:

方法 1:使用限制条款

         select columnA1, columnA2 from tableA order by [columnA3] asc Limit 100000000
         union distinct
         select columnB1, columnB2 from tableB
Run Code Online (Sandbox Code Playgroud)

我已经使用很少的数据集测试了这种行为,并且它似乎始终如一地工作。此外,在 MySQL 的文档 ( http://dev.mysql.com/doc/refman/5.1/en/union.html ) 中也提到了这种行为:其中行出现在最终结果中,因为 UNION 默认生成一组无序的行。因此,在此上下文中使用 ORDER BY 通常与 LIMIT 结合使用,以便它用于确定要为 SELECT 检索的选定行的子集,即使它不一定影响这些行在最终的 UNION 结果。如果 ORDER BY 在 SELECT 中没有 LIMIT,它会被优化掉,因为无论如何它都不会产生任何影响。”

请注意,选择 10000000000 的 LIMIT 没有特别的原因,只是要有足够高的数字以确保我们涵盖所有情况。

方法 2:如下所示的嵌套查询也有效。

        select column1, column2 from 
        ( select column1, column2 order by [columnA3] asc ) alias1
        union distinct
        ( select column1, column2 from tableB )
Run Code Online (Sandbox Code Playgroud)

我找不到嵌套查询起作用的原因。网上有一些参考资料(比如 Phil McCarley 在http://dev.mysql.com/doc/refman/5.0/en/union.html 的参考资料),但没有来自 MySQL 的官方文档。