SQL集合運算 差集 並集 交集

SQL-3標準中提供了三種對檢索結果進行集合運算的命令:並集UNION;交集INTERSECT;差集EXCEPT(在Oracle中叫作 MINUS)。在有些數據庫中對此的支持不夠充分,如MySql中只有UNION,沒有其餘兩種。實際上這些運算均可以經過普通的SQL來實現,雖然有時有些繁瑣。mysql

假設有兩個表(或視圖)s,t,s中有兩個字段sa,sb;t中有兩個字段ta,tb;sql

差集EXCEPT:

PLAIN TEXT數據庫

SQL:
spa

  1. SELECTsaFROMsorm

  2. EXCEPTget

  3. SELECTtaFROMt;it

能夠寫做io

PLAIN TEXT技巧

SQL:
語法

  1. SELECTsaFROMs

  2. WHEREsaNOTIN

  3.    (SELECTtaFROMt)

上面的例子中忽略了對s和t單獨的條件,這些總能夠加入AND條件完成,或者使用視圖。若是是多個字段比較麻煩,如:

PLAIN TEXT

SQL:

  1. SELECTsa, sbFROMs

  2. EXCEPT

  3. SELECTta, tbFROMt;

須要寫成

PLAIN TEXT

SQL:

  1. SELECTsa, sbFROMs

  2. WHERE(sa, sb)NOTIN

  3.    (SELECTta, tbFROMt)

 

上面使用的語法不見得數據庫都支持。好在不支持EXCEPT的MySQL支持這種語法,而不支持這種語法的MSSQL又支持EXCEPT。

注意對於這樣的row constructors(Mysql術語),是和下面寫法(以及其餘相似寫法)不等價的。

PLAIN TEXT

SQL:

  1. SELECTsa, sbFROMs

  2. WHEREsaNOTIN

  3.    (SELECTtaFROMt)

  4. ANDsbNOTIN

  5.    (SELECTtbFROMt)

在MSSQL中的一個解決技巧是,把這兩個字段(假設字符類型)拼起來,即

PLAIN TEXT

SQL:

  1. SELECTsa, sbFROMs

  2. WHEREsa+sbNOTIN

  3.    (SELECTta+tbFROMt)

 

交集INTERSECT:

PLAIN TEXT

SQL:

  1. SELECTsaFROMs

  2. INTERSECT

  3. SELECTtaFROMt;

能夠寫成

PLAIN TEXT

SQL:

  1. SELECTsaFROMs

  2. WHEREsa IN

  3.    (SELECTtaFROMt)

固然也能夠寫成

PLAIN TEXT

SQL:

  1. SELECTsaFROMs

  2. WHEREEXISTS

  3.    (SELECT*FROMtWHEREt.ta=s.sa)

或者使用鏈接

PLAIN TEXT

SQL:

  1. SELECTsaFROMs, t

  2. WHEREsa = ta

 

實際上這幾個語句都有點問題,就是INTERSECT在出現重複時的語義問題。按照SQL-3標準,相似UNION,能夠有明確的 INTERSECT ALL或者INTERSECT DISTINCT語法。通常的INTERSECT實現並無明確這一點,並且從邏輯上講意義也不大。那麼當s或t中出現重複的時,如sa='x'的有2 個,sb='x'的有3個,使用上面的子查詢將返回2行,使用鏈接將返回6行,固然這兩個語句均可以加上一個DISTINCT,就實現了 INTERSECT DISTINCT語義了。

並集UNION:

MySql從4.0開始就支持UNION(ALL 和 DISTINCT)了,爲完整起見,也列舉一下。
其實實現這樣一個結果是很麻煩的

PLAIN TEXT

SQL:

  1. SELECTsaFROMs

  2. UNIONDISTINCT

  3. SELECTtaFROMt;

須要使用外鏈接,並且是Full的外鏈接

PLAIN TEXT

SQL:

  1. SELECTDISTINCTNVL(s.sa, t.ta)

  2. FROMs FULLOUTERJOINtON(s.sa=t.ta)

 

上面的例子中我使用了Oracle的語法,實際上MySql不支持FULL OUTER JOIN(雖然支持LEFT和RIGHT OUTER JOIN),好在MySql支持UNION。

對於UNION ALL語義,我尚未想出來用普通查詢如何實現,若是在上面語句中去掉DISTINCT,結果確定不對。

相關文章
相關標籤/搜索