共用方式為


使用 Access SQL 執行聯結

在 Access 這類的關聯式資料庫系統中,經常需要同時從一個以上的資料表中擷取資訊。 若要完成此操作,可以使用 SQL JOIN 陳述式,從已定義關聯性 (無論是一對一、一對多或多對多關聯) 的資料表中擷取記錄。

INNER JOIN

INNER JOIN 又稱為等聯結 (Equi-Join),是最常使用的聯結類型。 這種聯結可以透過比對資料表之間共同的欄位值,從兩個以上的資料表中擷取資料列。 聯結的欄位必須具有相似的資料類型,且您無法聯結 MEMO 或 OLEOBJECT 資料類型。

若要建立 INNER JOIN 陳述式,請在 SELECT 陳述式的 FROM 子句中使用 INNER JOIN 關鍵字。

以下範例使用 INNER JOIN ,來建立包含發票的日期及金額以及具有發票之所有客戶的結果集。

SELECT [Last Name], InvoiceDate, Amount 
   FROM tblCustomers INNER JOIN tblInvoices 
   ON tblCustomers.CustomerID=tblInvoices.CustomerID 
   ORDER BY InvoiceDate 

請注意,數據表名稱會除以 INNER JOIN 關鍵詞,而關係型比較會在 ON 關鍵詞之後。 針對關係型比較,您也可以使用 <、 >、 <=、 >=或 <> 運算符,也可以使用 BETWEEN 關鍵詞。 另請注意,兩個資料表的 [識別碼] 欄位只能用於關聯性比較;它們不是最終結果集的一部分。

若要進一步限定 SELECT 語句,您可以在 ON 子句中的聯結比較之後使用 WHERE 子句。

下列範例會將結果集縮小為只包括 1998 年 1 月 1 日之後的發票。

SELECT [Last Name], InvoiceDate, Amount 
   FROM tblCustomers INNER JOIN tblInvoices 
   ON tblCustomers.CustomerID=tblInvoices.CustomerID 
   WHERE tblInvoices.InvoiceDate > #01/01/1998# 
   ORDER BY InvoiceDate 

當您必須聯結多個數據表時,可以巢狀處理 INNER JOIN 子句。 下列範例就是以先前的 SELECT 陳述式為基礎建立結果集,但是也為 [tblShipping] 資料表加入 INNER JOIN ,以包括每個客戶所在的縣市。

SELECT [Last Name], InvoiceDate, Amount, City, State 
   FROM (tblCustomers INNER JOIN tblInvoices 
   ON tblCustomers.CustomerID=tblInvoices.CustomerID) 
      INNER JOIN tblShipping 
      ON tblCustomers.CustomerID=tblShipping.CustomerID 
   ORDER BY InvoiceDate 

請注意,第一個 JOIN 子句會以括弧括住,使其在邏輯上與第二個 JOIN 子句分開。 您也可以使用 FROM 子句中第二個資料表名稱的別名,將數據表聯結至本身。 假設您想要尋找具有重複姓氏的所有客戶記錄。 若要這麼做,您可以建立第二個數據表的別名 “A”,並檢查是否有不同的名字。

SELECT tblCustomers.[Last Name], 
   tblCustomers.[First Name] 
   FROM tblCustomers INNER JOIN tblCustomers AS A 
   ON tblCustomers.[Last Name]=A.[Last Name] 
   WHERE tblCustomers.[First Name]<>A.[First Name] 
   ORDER BY tblCustomers.[Last Name] 

OUTER JOIN

An OUTER JOIN is used to retrieve records from multiple tables while preserving records from one of the tables, even if there is no matching record in the other table. There are two types of OUTER JOINs that the Access database engine supports: LEFT OUTER JOINs and RIGHT OUTER JOINs.

Think of two tables that are beside each other, a table on the left and a table on the right. LEFT OUTER JOIN 會選取右側數據表中符合關係比較準則的所有數據列,也會從左側數據表中選取所有數據列,即使右側數據表中沒有相符專案也一樣。 The RIGHT OUTER JOIN is simply the reverse of the LEFT OUTER JOIN; all rows in the right table are preserved instead.

舉例而言,假設要決定每個客戶的總發票金額,但是某客戶沒有發票,那麼就要顯示「無」字來表示此客戶。

SELECT [Last Name] & ', ' &  [First Name] AS Name, 
   IIF(Sum(Amount) IS NULL,'NONE',Sum(Amount)) AS Total 
   FROM tblCustomers LEFT OUTER JOIN tblInvoices 
   ON tblCustomers.CustomerID=tblInvoices.CustomerID 
   GROUP BY [Last Name] & ', ' &  [First Name] 

上一個 SQL 語句中會發生幾件事。 第一種是使用字串串連運算子 「&」。。 此運算子可讓您將兩個或多個字段聯結為一個字元串。 如果 If) 語句 (,則第二種是立即的,其會檢查總計是否為 null。 如果是,語句會傳回 「NONE」 這個字。如果總計不是 Null,則會傳回值。 最後一件事是 OUTER JOIN 子句。 使用 LEFT OUTER JOIN 會保留左資料表中的數據列,讓您看到所有客戶,甚至是沒有發票的客戶。

在多個資料表聯結中,OUTER JOIN 可以在 INNER JOIN 內部形成巢狀,而 INNER JOIN 卻不可以在 OUTER JOIN 內部形成巢狀。

卡笛生乘積運算

討論聯結時經常會提到卡笛生乘積運算。 笛卡兒乘積定義為「所有數據表中所有數據列的所有可能組合」。例如,如果您要聯結兩個數據表,而不需要任何種類的限定性或聯結類型,您會得到笛卡兒乘積。

SELECT * 
   FROM tblCustomers, tblInvoices 

這並不是最佳作法,尤其是在資料表包含大量資料列時。 您應該一律都限定聯結的條件,以免建立卡笛生乘積運算。

UNION 運算子

UNION 運算子又稱為聯集查詢,儘管就技術上來說它並不屬於聯結,但是因為它與某些類型的聯結相似,都涉及到將多個資料來源的資料合併為一個結果集,所以也在這裡一併介紹。 UNION 運算子可用於將資料表、 SELECT 陳述式或查詢的資料組合在一起,同時移除任何重複的資料列。 這兩個數據源的欄位數目必須相同,但字段不一定要是相同的數據類型。 假設您的 Employees 數據表具有與 Customers 數據表相同的結構,而且您想要結合這兩個數據表來建立名稱和電子郵件地址清單。

SELECT [Last Name], [First Name], Email 
   FROM tblCustomers 
UNION 
SELECT [Last Name], [First Name], Email 
   FROM tblEmployees 

若要從這兩個數據表擷取所有欄位,您可以使用 TABLE 關鍵詞,如下所示。

TABLE tblCustomers 
UNION 
TABLE tblEmployees 

UNION 運算符不會顯示兩個數據表中完全重複的任何記錄,但您可以在 UNION 關鍵詞後面使用 ALL 述詞來覆寫,如下所示:

SELECT [Last Name], [First Name], Email 
   FROM tblCustomers 
UNION ALL 
SELECT [Last Name], [First Name], Email 
   FROM tblEmployees 

TRANSFORM 陳述式

TRANSFORM 陳述式又稱為交叉資料表查詢,儘管就技術上來說它也不屬於聯結,但是因為它與某些類型的聯結相似,都涉及到將多個資料來源的資料合併為一個結果集,所以也在這裡一併介紹。

TRANSFORM 陳述式可用於計算記錄的加總、平均、計數或其他類型的彙總合計。 然後會以格線或試算表格式顯示資訊,並將資料以縱向 (資料列) 及橫向 (資料行) 的方式進行分組。 TRANSFORM 語句的一般形式如下。

   TRANSFORM aggregating function 
   SELECT statement 
   PIVOT column heading field 

例如,如果您想要建置數據工作表,以每年顯示每位客戶的發票總計。 那麼縱向標題就是客戶名稱,橫向標題則是年份。 您可以修改上述 SQL 陳述式,以符合 TRANSFORM 陳述式。

TRANSFORM 
IIF(Sum([Amount]) IS NULL,'NONE',Sum([Amount])) 
   AS Total 
SELECT [Last Name] & ', ' & [First Name] AS Name 
      FROM tblCustomers LEFT JOIN tblInvoices 
      ON tblCustomers.CustomerID=tblInvoices.CustomerID 
      GROUP BY [Last Name] & ', ' & [First Name] 
PIVOT Format(InvoiceDate, 'yyyy') 
   IN ('1996','1997','1998','1999','2000') 

請注意,匯總函式是 Sum 函式、垂直標題位於 SELECT 語句的 GROUP BY 子句中,而水平標題是由 PIVOT 關鍵詞後面列出的欄位所決定。

支援和意見反應

有關於 Office VBA 或這份文件的問題或意見反應嗎? 如需取得支援服務並提供意見反應的相關指導,請參閱 Office VBA 支援與意見反應