SQL 入門教程:創建組合(UNION)查詢


目錄匯總:SQL 零基礎入門教程

可用 UNION 操作符來組合數條 SQL 查詢。利用 UNION,可給出多條 SELECT 語句,將它們的結果組合成一個結果集。

一、使用 UNION

使用 UNION 很簡單,所要做的只是給出每條 SELECT 語句,在各條語句之間放上關鍵字 UNION

舉個例子,假如需要 Illinois、Indiana 和 Michigan 等美國幾個州的所有顧客的報表,還想包括不管位於哪個州的所有的 Fun4All。當然可以利用 WHERE 子句 來完成此工作,不過這次我們使用 UNION

如上所述,創建 UNION 涉及編寫多條 SELECT 語句。首先來看單條語句:

輸入▼

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI');

輸出▼

cust_name       cust_contact      cust_email
-----------     -------------     ------------
Village Toys    John Smith        sales@villagetoys.com
Fun4All         Jim Jones         jjones@fun4all.com
The Toy Store   Kim Howard        NULL

輸入▼

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All';

輸出▼

cust_name       cust_contact         cust_email
-----------     -------------        ------------
Fun4All         Jim Jones            jjones@fun4all.com
Fun4All         Denise L. Stephens   dstephens@fun4all.com

分析▼

第一條 SELECT 把 Illinois、Indiana、Michigan 等州的縮寫傳遞給 IN 子句,檢索出這些州的所有行。第二條 SELECT 利用簡單的相等測試找出所有 Fun4All。你會發現有一條記錄出現在兩次結果里,因為它滿足兩次的條件。

組合這兩條語句,可以如下進行:

輸入▼

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All';

輸出▼

cust_name       cust_contact        cust_email
-----------     -----------         ----------------
Fun4All         Denise L. Stephens  dstephens@fun4all.com
Fun4All         Jim Jones           jjones@fun4all.com
Village Toys    John Smith          sales@villagetoys.com
The Toy Store   Kim Howard          NULL

分析▼

這條語句由前面的兩條 SELECT 語句組成,之間用 UNION 關鍵字分隔。UNION 指示 DBMS 執行這兩條 SELECT 語句,並把輸出組合成一個查詢結果集。

為了便於參考,這里給出使用多條 WHERE 子句而不是 UNION 的相同查詢:

輸入▼

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI') OR cust_name='Fun4All';

在這個簡單的例子中,使用 UNION 可能比使用 WHERE 子句更為復雜。但對於較復雜的過濾條件,或者從多個表(而不是一個表)中檢索數據的情形,使用 UNION 可能會使處理更簡單。

提示:UNION 的限制

使用 UNION 組合 SELECT 語句的數目,SQL 沒有標准限制。但是,最好是參考一下具體的 DBMS 文檔,了解它是否對 UNION 能組合的最大語句數目有限制。

注意:性能問題

多數好的 DBMS 使用內部查詢優化程序,在處理各條 SELECT 語句前組合它們。理論上講,這意味着從性能上看使用多條 WHERE 子句條件還是 UNION 應該沒有實際的差別。不過我說的是理論上,實踐中多數查詢優化程序並不能達到理想狀態,所以最好測試一下這兩種方法,看哪種工作得更好。

二、UNION 規則

可以看到,UNION 非常容易使用,但在進行組合時需要注意幾條規則。

  • UNION 必須由兩條或兩條以上的 SELECT 語句組成,語句之間用關鍵字 UNION 分隔(因此,如果組合四條 SELECT 語句,將要使用三個 UNION 關鍵字)。
  • UNION 中的每個查詢必須包含相同的列、表達式或聚集函數(不過,各個列不需要以相同的次序列出)。
  • 列數據類型必須兼容:類型不必完全相同,但必須是 DBMS 可以隱含轉換的類型(例如,不同的數值類型或不同的日期類型)。

說明:UNION 的列名

如果結合 UNION 使用的 SELECT 語句遇到不同的列名,那么會返回什么名字呢?比如說,如果一條語句是 SELECT prod_name,而另一條語句是 SELECT productname,那么查詢結果返回的是什么名字呢?

答案是它會返回第一個名字,舉的這個例子就會返回 prod_name,而不管第二個不同的名字。這也意味着你可以對第一個名字使用別名,因而返回一個你想要的名字。

這種行為帶來一個有意思的副作用。由於只使用第一個名字,那么想要排序也只能用這個名字。拿我們的例子來說,可以用 ORDER BY prod_name 對結果排序,如果寫成 ORDER BY productname 就會出錯,因為查詢結果里沒有叫作 productname 的列。

如果遵守了這些基本規則或限制,則可以將 UNION 用於任何數據檢索操作。

三、包含或取消重復的行

回到一節,我們看看所用的 SELECT 語句。注意到在分別執行語句時,第一條 SELECT 語句返回 3 行,第二條 SELECT 語句返回 2 行。而在用 UNION 組合兩條 SELECT 語句后,只返回 4 行而不是 5 行。

UNION 從查詢結果集中自動去除了重復的行;換句話說,它的行為與一條 SELECT 語句中使用多個 WHERE 子句條件一樣。因為 Indiana 州有一個 Fun4All 單位,所以兩條 SELECT 語句都返回該行。使用 UNION 時,重復的行會被自動取消。

這是 UNION 的默認行為,如果願意也可以改變它。事實上,如果想返回所有的匹配行,可使用 UNION ALL 而不是 UNION

請看下面的例子:

輸入▼

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION ALL
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All';

輸出▼

cust_name       cust_contact         cust_email
-----------     -------------        ------------
Village Toys    John Smith           sales@villagetoys.com
Fun4All         Jim Jones            jjones@fun4all.com
The Toy Store   Kim Howard           NULL
Fun4All         Jim Jones            jjones@fun4all.com
Fun4All         Denise L. Stephens   dstephens@fun4all.com

分析▼

使用 UNION ALL,DBMS 不取消重復的行。因此,這里返回 5 行,其中有一行出現兩次。

提示:UNIONWHERE

這一部分一開始我們說過,UNION 幾乎總是完成與多個 WHERE 條件相同的工作。UNION ALLUNION 的一種形式,它完成 WHERE 子句完成不了的工作。如果確實需要每個條件的匹配行全部出現(包括重復行),就必須使用 UNION ALL,而不是 WHERE

四、對組合查詢結果排序

SELECT 語句的輸出用 ORDER BY 子句排序。在用 UNION 組合查詢時,只能使用一條 ORDER BY 子句,它必須位於最后一條 SELECT 語句之后。對於結果集,不存在用一種方式排序一部分,而又用另一種方式排序另一部分的情況,因此不允許使用多條 ORDER BY 子句。

下面的例子對前面 UNION 返回的結果進行排序:

輸入▼

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All'
ORDER BY cust_name, cust_contact;

輸出▼

cust_name       cust_contact         cust_email
-----------     -------------        -------------
Fun4All         Denise L. Stephens   dstephens@fun4all.com
Fun4All         Jim Jones            jjones@fun4all.com
The Toy Store   Kim Howard           NULL
Village Toys    John Smith           sales@villagetoys.com

分析▼

這條 UNION 在最后一條 SELECT 語句后使用了 ORDER BY 子句。雖然 ORDER BY 子句似乎只是最后一條 SELECT 語句的組成部分,但實際上 DBMS 將用它來排序所有 SELECT 語句返回的所有結果。

說明:其他類型的 UNION

某些 DBMS 還支持另外兩種 UNION:EXCEPT(有時稱為 MINUS)可用來檢索只在第一個表中存在而在第二個表中不存在的行;而 INTERSECT 可用來檢索兩個表中都存在的行。實際上,這些 UNION 很少使用,因為相同的結果可利用聯結得到。

 

提示:操作多個表

為了簡單,本部分中的例子都是使用 UNION 來組合針對同一表的多個查詢。實際上,UNION 在需要組合多個表的數據時也很有用,即使是有不匹配列名的表,在這種情況下,可以將 UNION 與別名組合,檢索一個結果集。

請參閱

(完)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM