2011-09-26 90 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的官方文檔。