SQL Server 基礎知識:使用 SQL Joins

在关系型数据库中,像 SQL Server 这样的数据库中,SQL JOIN 语句用于根据这些表之间的数据关系查询、连接和检索多个表中的数据。您可以使用 SQL JOIN 语句与两个或更多个表一起使用,它基本上返回在不同表中具有匹配值的记录。在本教程中,我将解释如何使用最常见的 SQL JOIN 类型,包括 SQL INNER JOIN、SQL LEFT JOIN、SQL RIGHT JOIN 和 SQL OUTER JOIN。

SQL Joins 是在使用关系型数据库时必须使用的重要功能。它们主要通过 SQL SELECT 语句执行。您可以在我之前的 SQL Servers 文章中了解有关使用 T-SQL SELECT 语句入门的更多信息: Using SQL SELECT and the WHERE and HAVING Clauses to Retrieve Data

广告

SQL INNER JOIN

SQL INNER JOIN 操作通过合并在两个或更多个表中具有匹配值的行来创建结果集。这可能是 T-SQL 中最常用的连接操作。SQL INNER JOIN 仅返回具有匹配值的行,并且用于检索出现在所有表中的数据。

以下的圖表說明了SQL的內部連接操作如何與兩個表格一起運作。

How an SQL INNER JOIN operation works with two tables (Image credit: Petri/Michael Otey)

內部連接的語法非常直觀。作為你的SELECT語句的一部分,你指定了要連接的兩個表格以及要使用的列來匹配行。

讓我們更仔細地看看AdventureWorksLT2019範例資料庫中的兩個表格。如果我們使用SalesLT.Customer和SalesLT.SalesOrderHeader表格,我們可以使用SQL的內部連接來檢索SalesLT.Customer表格中的客戶訂單,方法是在兩個表格上使用共同的CustomerID列來連接這兩個表格。

廣告

以下是你可以使用的T-SQL查詢:

USE AdventureWorksLT2019

SELECT c.CustomerID, c.FirstName, c.LastName, soh.SalesOrderID, soh.OrderDate 
FROM SalesLT.Customer c
INNER JOIN SalesLT.SalesOrderHeader soh ON c.CustomerID = soh.CustomerID

以下是SQL內部連接語法的工作原理:

  • 在這裡,你可以看到我們從SalesLT.Customer表格中選擇了’CustomerID’、’FirstName’和’LastName’列,以及從SalesLT.SalesOrderHeader表格中選擇了’SalesOrderID’和’OrderDate’列。
  • ‘c’和‘soh’是簡寫的表格別名,可以消除在引用列時總是需要使用完整表格名稱的需求。
  • 我們使用INNER JOIN關鍵字來連接兩個表格。ON關鍵字指定用於連接的列。這裡是’CustomerID’列。

這個查詢將返回一個結果集,其中包括每個已下訂單的客戶的「CustomerID」、「FirstName」、「LastName」、「SalesOrderID」和「OrderDate」列,如你在下圖中所看到的。

The result of our SQL INNER JOIN query (Image credit: Petri/Michael Otey)

SQL LEFT JOIN

SQL LEFT OUTER JOIN 操作也會通過匹配我們兩個先前表格之間的行來創建一個結果集。然而,使用 SQL LEFT JOIN,如果左表中沒有匹配的記錄,它將顯示那些具有空值的記錄。

廣告

當你希望從第一個表中包括所有行並且只包括第二個表中的匹配行時,這是非常有用的,即使右表中沒有匹配。如果沒有匹配,SQL LEFT OUTER JOIN 將在右表的列中返回空值。

下面的圖示說明了 SQL LEFT OUTER JOIN 操作如何與兩個表一起使用。

How an SQL LEFT OUTER JOIN works with two tables (Image credit: Petri/Michael Otey)

LEFT JOIN 的語法也非常簡單。在 SELECT 語句的一部分中,您指定要加入的兩個表、用於匹配行的列以及 LEFT JOIN 子句。

讓我們更仔細地看一下 AdventureWorksLT2019 數據庫中的兩個表。例如,要檢索所有客戶及其任何訂單,您可以使用 SalesLT.Customer 和 SalesLT.SalesOrderHeader 表,並執行如下列表中所示的 LEFT JOIN:

USE AdventureWorksLT2019

SELECT c.CustomerID, c.FirstName, c.LastName, soh.SalesOrderID, soh.OrderDate
FROM SalesLT.Customer c 
LEFT JOIN SalesLT.SalesOrderHeader soh ON c.CustomerID = soh.CustomerID
  • 在這個例子中,我們從 SalesLT.Customer 和 SalesLT.SalesOrderHeader 表中選擇了「CustomerID」、「FirstName」、「LastName」、「SalesOrderID」和「OrderDate」列。
  • 我們使用 LEFT JOIN 關鍵字來連接兩個表,並使用 ON 關鍵字在 ‘CustomerID’ 列上連接兩個表。

你可以在下面的圖中看到這個 SQL LEFT JOIN 查詢的結果。

The results of our SQL LEFT JOIN query (Image credit: Petri/Michael Otey)

這個查詢將返回一個結果集,其中包括 SalesLT.Customer 表中的所有客戶以及 SalesLT.SalesOrderHeader 表中的任何相應的訂單信息。如果一個客戶在 SalesLT.SalesOrderHeader 表中沒有任何訂單,那麼該表中的列將為 null。你可以在上一個圖中看到幾個空值。

SQL RIGHT JOIN

正如你所猜測的,SQL RIGHT OUTER JOIN 操作基本上是 LEFT OUTER JOIN 的相反。RIGHT OUTER JOIN 從右表(表2)選擇數據,並將此數據與左表(表1)的行匹配。

RIGHT JOIN 返回一個結果集,其中包括右表中的所有行,即使它們在左表中沒有匹配的行。如果右表中的一行在左表中沒有匹配的行,則來自左表的列的結果集將為 null。

下面的圖示了如何使用右 JOIN 與兩個表進行操作:

How a right JOIN works with two tables (Image credit: Petri/Michael Otey)

我們可以使用 AdventuresLT2019 數據庫中的 SalesLT.Customer 和 SalesLT.SalesOrderHeader 來展示這一點。要檢索所有訂單及其相應的客戶信息,可以使用 RIGHT JOIN 查詢,如下例所示:

USE AdventureWorksLT2019

SELECT c.CustomerID, c.FirstName, c.LastName, soh.SalesOrderID, soh.OrderDate
FROM SalesLT.Customer c 
RIGHT JOIN SalesLT.SalesOrderHeader soh ON c.CustomerID = soh.CustomerID
  • 在這個例子中,我們從SalesLT.Customer和SalesLT.SalesOrderHeader表中選擇‘CustomerID’、‘FirstName’、‘LastName’、‘SalesOrderID’和‘OrderDate’列。
  • 使用RIGHT JOIN關鍵字來連接這兩個表,ON關鍵字指定我們在‘CustomerID’列上連接這兩個表。

這個查詢將返回一個結果集,其中包含SalesLT.SalesOrderHeader表中的所有訂單,以及如果有的話,來自SalesLT.Customer表的相應客戶信息。如果一個訂單在SalesLT.Customer表中沒有相應的客戶,結果集中的客戶列將為空。

您可能會注意到這個查詢非常類似於前面的查詢。然而,LEFT JOIN導致了來自SaleOrderHeader表的許多行具有空值。然而,我們的最後一個查詢在來自SaleOrderHeader表的行中沒有空值。

我們的SQL RIGHT OUTER JOIN操作的結果顯示在下圖中。

The results of our SQL RIGHT OUTER JOIN operation (Image credit: Petri/Michael Otey)

SQL OUTER JOIN

SQL OUTER JOIN不是最常見的連接操作類型。有時被稱為FULL JOIN,OUTER JOIN查詢不僅檢索匹配的行,還檢索不匹配的行。換句話說,當左表或右表中有匹配時,它會返回連接表中的數據。

正如您可能猜測的那樣,這往往會產生比其他連接類型更大的結果集。下圖說明了SQL OUTER JOIN如何與兩個表一起工作。

How an SQL OUTER JOIN works with two tables (Image credit: Petri/Michael Otey)

I’ll give you an example of an SQL OUTER JOIN operation using the SalesLT.SalesOrderHeader and SalesLT.SalesOrderDetail tables. Here, we want to retrieve all sales orders and their associated details, including orders that don’t have any details records.

為了做到這一點,我們可以使用全外部連接。這也會返回任何未具有相應銷售訂單標頭行的銷售訂單細節行。在大多數正常情況下,所有銷售訂單細節行應該具有相應的銷售訂單標頭行,但如果出現應用程序或系統錯誤,這可能不是這種情況,這可以幫助檢測。

這是一個T-SQL查詢,顯示了一個全外部連接的示例:

USE AdventureWorksLT2019

SELECT soh.SalesOrderID, soh.OrderDate, sod.ProductID, sod.OrderQty, sod.UnitPrice
FROM SalesLT.SalesOrderHeader soh
FULL OUTER JOIN SalesLT.SalesOrderDetail sod
ON soh.SalesOrderID = sod.SalesOrderID
  • 在這個示例中,我們從SalesLT.SalesOrderHeader和SalesLT.SalesOrderDetail表中選擇了’SalesOrderID’、’OrderDate’、’ProductID’、’Quantity’和’UnitPrice’列。
  • 我們使用了FULL OUTER JOIN關鍵詞來連接兩個表,並使用ON關鍵詞來指定使用SalesOrderID列來連接兩個表。
  • 此查詢將返回一個結果集,其中包括SalesLT.SalesOrderHeader表中的所有銷售訂單,以及其來自SalesLT.SalesOrderDetail表的相應詳細信息。它還將包括SalesLT.SalesOrderDetail表中的所有詳細信息,以及如果可用的話,其相應的訂單標頭信息。
  • 如果銷售訂單在SalesLT.SalesOrderDetail表中沒有任何細節,則列將為NULL。如果一個細節在SalesLT.SalesOrderHeader表中沒有相應的銷售訂單,那麼銷售訂單列將為NULL。

全外部連接操作的結果如下圖所示。

The results of our FULL OUTER JOIN operation (Image credit: Petri/Michael Otey)

學習SQL連接基礎知識

在這個教程中,我介紹了最常見的不同類型的SQL JOINS。我展示了如何使用INNER JOIN、LEFT JOIN、RIGHT JOIN和OUTER JOIN,並解釋了它們之間的區別以及它們可以在哪裡使用。在即將到來的文章中,我將介紹一些不太常見的JOIN,比如CROSS JOIN和SELF JOIN,所以請密切關注 Petri!

相關文章

Source:
https://petri.com/sql-join/