2010-01-18 128 views
3

上週我驚訝地發現,sybase 12不支持完全外連接。 但它發生在我身上,一個完整的外部聯接應該與一個左外部聯接相同,並與同一個sql的右外部聯接聯合。 有人可以想到這不會成立的理由嗎?如何在沒有完全外連接的情況下完成全外連接

+0

當你嘗試過時發生了什麼? – gary 2010-01-18 22:35:18

+0

我得到了什麼似乎是正確的數據,但一個測試案例並不一定完全回答這個問題。 – stu 2010-01-20 16:18:16

回答

1

UNION -ing two OUTER JOIN語句應該會導致重複的行表示您從INNER JOIN獲得的數據。您可能必須對由UNION生成的數據集執行SELECT DISTINCT。通常如果你不得不使用SELECT DISTINCT這意味着它不是一個設計良好的查詢(或者我聽說過)。

+1

@Josh。 'DISTINCT'不僅僅是這裏所需要的;只是排除'ALL'。是的,如果你必須使用'DISTINCT'或'OUTER JOIN'這肯定表明有什麼問題;與數據庫設計,而不是代碼。 – PerformanceDBA 2011-01-19 23:12:02

1

如果你將它們與UNION ALL合併,你會得到重複。如果您僅使用UNION而不使用ALL,則它將過濾重複項,因此相當於全連接,但該查詢也會更昂貴,因爲它必須執行不同的排序。

+0

比聯盟全部貴得多,或者比本地完全外部聯接貴多了? – stu 2010-01-20 16:17:42

+0

@stu:兩者。即使本地完全連接在技術上與'UNION'一樣,支持完全連接的數據庫引擎也可以對其進行優化。話雖如此 - 完整的連接仍然非常緩慢,值得避免,如果可以的話。我不認爲我曾經使用它們。 – Aaronaught 2010-01-20 16:29:46

+1

Aaronaught。這是不正確的。 Sybase ASE 12爲此目的非常快速,它使用內部工作表和排序緩衝區。企業級引擎與免費軟件完全不同。 – PerformanceDBA 2011-01-19 10:43:17

0

UNION ALL左連接使用正確的連接,但將右連接限制爲僅基本表中不存​​在的行(如果連接存在,它們在表中不會爲空時,在連接上返回null)。

對於此代碼,您需要創建兩個表t1和t2。 t1應該有一列名爲c1,其中五行包含值1-5。 t2也應該有一個包含值2-6的五行的c1列。

完全外部聯接:

select * from t1 full outer join t2 on t1.c1=t2.c1 order by 1, 2; 

全外連接等效:

select t1.c1, t2.c1 from t1 left join t2 on t1.c1=t2.c1 
union all 
select t1.c1, t2.c1 from t1 right join t2 on t1.c1=t2.c1 
where t1.c1 is null 
order by 1, 2; 

注,其中右側條款加入選擇將結果限制爲只有那些不會重複。

+1

@Leigh。 1)不能在NOT NULL列中放置NULL,代碼將不起作用2)這是oracle代碼,我們在Sybase中沒有'dual'或'row_ids'。 – PerformanceDBA 2011-01-19 23:05:15

+1

1)我以爲你的意思是你所說的;我沒有意識到你正在說明斯圖明顯理解的外部聯接的定義(請參閱他的帖子)。已清除2)刪除'ALL'(詳見其他兩個答案)和'WHERE'子句。首先,你是包含愚蠢的;那麼你就排除了這些蠢事;通過排除「ALL」,首先避免選擇模糊更便宜,更直接,然後不需要「WHERE」。 – PerformanceDBA 2011-01-21 04:07:46

+0

@PerformanceDBA刪除'ALL'是爲了讓'UNION'能刪除重複項。我的版本在'UNION ALL'之前消除了重複,而'UNION'版本在'UNION'上消除了它們。你可能是對的,後者可能會更便宜,這取決於數據集;無論此解決方案是否仍然有效。 – 2011-01-21 05:32:44

0
  1. 首先,我不知道你爲什麼使用12.x.在2009年4月3日獲得通知後,它於2009年12月31日發佈了EndOfLifed。2009年1月發佈了15.0.2(第一個固體版本)。15.5好得多,於2009年12月2日發佈,所以你是兩個主要版本,並且至少13個月,過時了。

  2. ASE 12.5.4具有新的Join語法。 (你沒有指定,你可能會在12.5.0.3之前發佈)。

  3. DB2和Sybase沒有執行FULL OUTER JOIN,因爲您已經確定的原因是:它由LEFT ... UNION ... RIGHT覆蓋,沒有ALL。這不是「不支持」FOJ的情況;這是關鍵字丟失的情況。

  4. 然後你有Sybase和DB2的類型,將一般不會使用外連接更不用說FOJs,因爲它們的數據庫更趨於規範化問題等

  5. 末,有非常普通的SQL你可以在任何版本的Sybase中使用,這些版本將提供FOJ的功能,並且在12.x上將明顯更快;在15.x上稍微快一點。它有點像RANK()函數:如果你可以編寫一個子查詢,這是非常不必要的。

  6. 第二個原因是它不需要FULL OUTER,就像一些低端引擎那樣,是因爲新的優化器速度非常快,並且查詢已完全標準化。 IE瀏覽器。它一次執行左和右。

  7. 根據你的SARGs和DataType不匹配等等,它可能仍然需要進行排序合併,但是也可以在所有三個級別進行流式傳輸:磁盤I/O子系統;引擎);和網絡處理程序。如果你的表是分區的,那麼它在這個層次上被並行化。

  8. 如果您的服務器沒有配置結果集是非常大的,你可能需要增加proc cache sizenumber of sort buffers。就這樣。