如何利用 SQL UNION 操作符將多條 SELECT 語句組合成一個結果集

来源:https://www.cnblogs.com/vin-c/archive/2022/05/18/16284357.html
-Advertisement-
Play Games

本文介紹如何利用 SQL UNION 操作符將多條 SELECT 語句組合成一個結果集。使用 UNION 可極大地簡化複雜的 WHERE 子句,簡化從多個表中檢索數據的工作。 一、組合查詢 多數 SQL 查詢只包含從一個或多個表中返回數據的單條 SELECT 語句。但是,SQL 也允許執行多個查詢( ...


目錄

本文介紹如何利用 SQL UNION 操作符將多條 SELECT 語句組合成一個結果集。使用 UNION 可極大地簡化複雜的 WHERE 子句,簡化從多個表中檢索數據的工作。

一、組合查詢

多數 SQL 查詢只包含從一個或多個表中返回數據的單條 SELECT 語句。但是,SQL 也允許執行多個查詢(多條 SELECT 語句),並將結果作為一個查詢結果集返回。

這些組合查詢通常稱為並(union)或複合查詢(compound query)。

主要有兩種情況需要使用組合查詢:

  • 在一個查詢中從不同的表返回結構數據;
  • 對一個表執行多個查詢,按一個查詢返回數據。

提示:組合查詢和多個 WHERE 條件

多數情況下,組合相同表的兩個查詢所完成的工作與具有多個 WHERE 子句條件的一個查詢所完成的工作相同。

換句話說,任何具有多個 WHERE 子句的 SELECT 語句都可以作為一個組合查詢,在下麵可以看到這一點。

二、創建組合查詢

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

2.1 使用 UNION

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

舉個例子,假如需要 IllinoisIndianaMichigan 等美國幾個州的所有顧客的報表,還想包括不管位於哪個州的所有的 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        [email protected]
Fun4All         Jim Jones         [email protected]
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            [email protected]
Fun4All         Denise L. Stephens   [email protected]

第一條 SELECTIllinoisIndianaMichigan 等州的縮寫傳遞給 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  [email protected]
Fun4All         Jim Jones           [email protected]
Village Toys    John Smith          [email protected]
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 應該沒有實際的差別。

不過我說的是理論上,實踐中多數查詢優化程式並不能達到理想狀態,所以最好測試一下這兩種方法,看哪種工作得更好。

2.2 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 用於任何數據檢索操作。

2.3 包含或取消重覆的行

回到 2.1 節,我們看看所用的 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           [email protected]
Fun4All         Jim Jones            [email protected]
The Toy Store   Kim Howard           NULL
Fun4All         Jim Jones            [email protected]
Fun4All         Denise L. Stephens   [email protected]

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

提示:UNIONWHERE

本文一開始我們說過,UNION 幾乎總是完成與多個 WHERE 條件相同的工作。

UNION ALLUNION 的一種形式,它完成 WHERE 子句完成不了的工作。

如果確實需要每個條件的匹配行全部出現(包括重覆行),就必須使用 UNION ALL,而不是 WHERE

2.4 對組合查詢結果排序

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   [email protected]
Fun4All         Jim Jones            [email protected]
The Toy Store   Kim Howard           NULL
Village Toys    John Smith           [email protected]

這條 UNION 在最後一條 SELECT 語句後使用了 ORDER BY 子句。

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

說明:其他類型的 UNION

某些 DBMS 還支持另外兩種 UNIONEXCEPT(有時稱為 MINUS)可用來檢索只在第一個表中存在而在第二個表中不存在的行;

INTERSECT 可用來檢索兩個表中都存在的行。實際上,這些 UNION 很少使用,因為相同的結果可利用聯結得到。

提示:操作多個表

為了簡單,本文中的例子都是使用 UNION 來組合針對同一表的多個查詢。

實際上,UNION 在需要組合多個表的數據時也很有用,即使是有不匹配列名的表,在這種情況下,可以將 UNION 與別名組合,檢索一個結果集。

三、小結

本文介紹瞭如何用 UNION 操作符來組合 SELECT 語句。利用 UNION,可以把多條查詢的結果作為一條組合查詢返回,不管結果中有無重覆。

使用 UNION 可極大地簡化複雜的 WHERE 子句,簡化從多個表中檢索數據的工作。

原文鏈接:https://www.developerastrid.com/sql/sql-union/

(完)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文例子參考《STM32單片機開發實例——基於Proteus虛擬模擬與HAL/LL庫》 源代碼:https://github.com/LanLinnet/STM33F103R6 項目要求 單片機每隔1秒採集一次溫度值(0~40℃),並通過串口輸出(ASCII格式)。 硬體設計 在第一節的基礎上,在P ...
  • ps命令 ps命令來自於英文片語”process status“的縮寫,其功能是用於顯示當前系統的進程狀態。使用ps命令可以查看到進程的所有信息,例如進程的號碼、發起者、系統資源使用占比(處理器與記憶體)、運行狀態等等。幫助我們及時的發現哪些進程出現”僵死“或”不可中斷“等異常情況。 經常會與kill ...
  • 一、概述 在眾多 Hadoop 版本中, CDH(Cloudera Hadoop) 是 Hadoop 眾多分支中比較出色的版本, 它由Cloudera 發行和維護。CDH 基於 Apache 的 Hadoop 進行重新構建,提供了基於 Web 頁面的群集部署和管理操作。Hadoop發行版除了社區的A ...
  • SpringDataRedis的序列化的一些問題 RedisTemplate可以接收任意Object作為值寫入Redis,但是如果不實現設置序列化器的化預設是採用JDK序列化,序列化後的結果可讀性差並且記憶體占用空間大,如下圖。 自定義RedisTemplate的序列化方式 key和 hashKey採 ...
  • 導讀: 今天和大家分享京東零售OLAP平臺的建設和場景的實踐,主要包括四大部分: 管控面建設 優化技巧 典型業務 大促備戰 -- 01 管控面建設 1. 管控面介紹 管控面可以提供高可靠高效可持續運維保障、快速部署小時交付的能力,尤其是針對ClickHouse這種運維較弱但是性能很高的OLAP核心引 ...
  • 本文介紹如何使用 UPDATE 和 DELETE 語句處理表中的數據,還介紹了為什麼 WHERE 子句對 UPDATE 和 DELETE 語句很重要。 一、更新數據 更新(修改)表中的數據,可以使用 UPDATE 語句。有兩種使用 UPDATE 的方式: 更新表中的特定行; 更新表中的所有行。 下麵 ...
  • 本文介紹如何使用 SQL INSERT 語句將數據插入到表中,如何用 INSERT SELECT 從其他表中導入行,如何用 SELECT INTO 將行導出到一個新表。 一、數據插入 毫無疑問,SELECT 是最常用的 SQL 語句了。但是,還有其他 3 個常用的 SQL 語句需要學習。第一個就是 ...
  • i,大家好,我是大D。今天繼續瞭解下 HBase 是如何寫入數據的,然後再講解一下一個比較經典的面試題。 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...