2011-09-26 87 views
1

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

例如:

select columnA1, columnA2 from tableA order by [columnA3] asc 
    union distinct 
    select columnB1, columnB2 from tableB 

当我运行此,我期待从子查询订购的记录(由[columnA3] ASC从TableA的顺序选择columnA1,columnA2)谁先(由顺序返回由columnA3 asc)接着是来自tableB的那些。

我假设我不能添加另一个虚拟列,因为这会使工会不同,不工作。所以,这是不行的:

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 
+0

为什么你不能添加一个虚拟列?它有什么问题? – Karolis

+0

@Karolis来自tableA和tableB的记录的唯一性基于pair {column1。列2}。添加一个虚拟列(以确保顺序)使它们不唯一。 – user965692

+0

是的,我明白你想从凯德的回答中做出什么:) – Karolis

回答

1
select column1, column2 from 
(select column1, column2, 1 as ORD from tableA 
union distinct 
select tableB.column1, tableB.column2, 2 as ORD from tableB 
    LEFT JOIN tableA 
     ON tableA.column1 = tableB.column1 AND tableA.column2 = tableB.column2 
    WHERE tableA.column1 IS NULL 
) order by ORD 

注意,UNION不仅去愚弄整个组独立,但套

或者内:

select column1, column2 from 
(select column1, column2, 1 as ORD from tableA 
union distinct 
select column1, column2, 2 as ORD from tableB 
WHERE (column1, column2) NOT IN (SELECT column1, column2 from tableA) 
) order by ORD 
+0

在工会内部秩序是没有意义的,你必须把它放在工会之外。 – Karolis

+0

@Karolis--对不起,他的例子就是这样。 –

+0

@CadeRoux - 不幸的是我不能做一个左连接,因为另一个表是巨大的,并导致性能瓶颈。事实上,这是我的第一个方法,但它太慢了。 – user965692

3

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

方法1:使用限制条款

  select columnA1, columnA2 from tableA order by [columnA3] asc Limit 100000000 
     union distinct 
     select columnB1, columnB2 from tableB 

我一直在使用几个数据集测试这种行为,它似乎工作始终。此外,在MySQL的文档(http://dev.mysql.com/doc/refman/5.1/en/union.html)中提到了这种行为: “对各个SELECT语句使用ORDER BY并不意味着行在最终结果中出现的顺序,因为默认情况下UNION会生成无序集的行。因此,在此上下文中使用ORDER BY通常与LIMIT结合使用,以便它用于确定要为SELECT检索的所选行的子集,即使它不一定会影响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) 

我找不到嵌套查询工作的原因。网上有一些参考文献(如Phil McCarley的文章,网址为http://dev.mysql.com/doc/refman/5.0/en/union.html),但没有MySQL的官方文档。