次の方法で共有


Access SQL を使用して結合を実行する

Access などのリレーショナル データベース システムでは、多くの場合、一度に複数のテーブルから情報を抽出する必要があります。 これを実現するには、SQL JOIN ステートメントを使用します。これにより、リレーションシップが定義されているテーブルからレコードを 1 対 1、1 対多、または多対多のいずれであっても取得できます。

内部結合 (INNER JOIN)

INNER 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 キーワード (keyword)の後であることに注意してください。 リレーショナル比較では、、><、=、=、>または <> 演算子を使用<することもできます。また、BETWEEN キーワード (keyword)を使用することもできます。 また、両方のテーブルの ID フィールドはリレーショナル比較でのみ使用されることに注意してください。これらは最終的な結果セットの一部ではありません。

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 

2 番目の JOIN 句との間でロジックの分離を保つために、最初の JOIN 句をかっこで囲んでいます。 FROM 句の 2 番目のテーブル名のエイリアスを使用して、テーブルをそれ自体に結合することもできます。 たとえば、姓が重複するすべての顧客のレコードを見つける必要があるとします。 これは、別名 "A" を作成して 2 番目のテーブルとして指定し、異なっている名をチェックすることによって実現できます。

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)

OUTER JOIN は、一致するレコードが他のテーブルに存在しない場合でも、いずれかのテーブルからレコードを保持しながら、複数のテーブルからレコードを取得するために使用されます。 Access データベース エンジンでサポートされる OUTER JOIN にはLEFT OUTER JOIN と RIGHT OUTER JOIN の 2 種類 があります

互いに隣り合う 2 つのテーブル、左側のテーブル、右側のテーブルを考えてみましょう。 LEFT OUTER JOIN は、リレーショナル比較条件に一致する右のテーブル内のすべての行を選択し、右側のテーブルに一致するものが存在しない場合でも、左のテーブルからすべての行を選択します。 右外部結合は、単に左外部結合の逆です。代わりに、右側のテーブル内のすべての行が保持されます。

たとえば、各顧客に発行された請求書の合計金額を調べたいが、請求書がない顧客については単語 "NONE" を表示することによってそのことを示したいとします。

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 ステートメントにはいくつかの特徴があります。 まず、文字列連結演算子 "&" を使用しています。 この演算子により、2 つ以上のフィールドを 1 つの文字列として結合することができます。 次に、合計金額が Null かどうかをチェックするために、IIf (Immediate If) ステートメントを使用しています。 その場合、ステートメントは "NONE" という単語を返します。合計が null でない場合は、値が返されます。 最後に、OUTER JOIN 句も使用しています。 LEFT OUTER JOIN を使用すると、左側のテーブル内の行が保持され、請求書を持っていない顧客も含め、すべての顧客が表示されます。

複数テーブルの結合では、INNER JOIN の内部に OUTER JOIN をネストできますが、INNER JOINOUTER JOIN の内部にネストすることはできません。

デカルト積

結合に関する説明でよく登場する用語に "デカルト積" があります。 デカルト積は、"すべてのテーブル内のすべての行のすべての可能な組み合わせ" として定義されます。たとえば、修飾または結合の種類を指定せずに 2 つのテーブルを結合する場合は、デカルト積を取得します。

SELECT * 
   FROM tblCustomers, tblInvoices 

このことは特に、テーブルに数百あるいは数千もの行が含まれるような場合には望ましくありません。 必ず何らかの形で結合を修飾して、デカルト積の作成を避けるようにしてください。

UNION 演算子

UNION 演算子 ( 共用 体クエリとも呼ばれます) は技術的には結合ではありませんが、複数のデータ ソースのデータを 1 つの結果セットに結合する必要があるため、これは一部の種類の結合に似ています。 UNION 演算子は、重複する行を除外しながら、テーブル、SELECT ステートメント、またはクエリからのデータを連結するために使用されます。 どちらのデータ ソースも同じ数のフィールドを持っている必要がありますが、フィールドが同じデータ型である必要はありません。 Customers テーブルと同じ構造の Employees テーブルがあり、両方のテーブルを組み合わせて名前とメール アドレスの一覧を作成するとします。

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

両方のテーブルからすべてのフィールドを取得するには、次のように TABLE キーワード (keyword)を使用できます。

TABLE tblCustomers 
UNION 
TABLE tblEmployees 

UNION 演算子では、両方のテーブルに完全に重複するレコードは表示されませんが、これは UNION キーワード (keyword)の後に ALL 述語を使用してオーバーライドできます。

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

TRANSFORM ステートメント

クロス集計クエリとも呼ばれる TRANSFORM ステートメントは、技術的には結合と見なされませんが、複数のデータ ソースのデータを 1 つの結果セットに結合する必要があるため、これは一部の種類の結合に似ています。

TRANSFORM ステートメントは、レコードに対する合計、平均、カウント、またはその他の種類の総計を計算するために使用されます。 このステートメントはその後、垂直方向 (行) および水平方向 (列) にグループ化されたデータを使用して、グリッドまたはスプレッドシート形式で情報を表示します。 TRANSFORM ステートメントの一般的な形式は次のとおりです。

   TRANSFORM aggregating function 
   SELECT statement 
   PIVOT column heading field 

サンプル シナリオでは、顧客ごとに請求書の合計金額を年単位で表示するデータシートを作成したいとします。 垂直方向の見出しは顧客の名前になり、水平方向の見出しは年になります。 TRANSFORM ステートメントに適合するように、前の SQL ステートメントを次のように修正できます。

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 キーワード (keyword)の後に一覧表示されるフィールドによって決定されます。

サポートとフィードバック

Office VBA またはこの説明書に関するご質問やフィードバックがありますか? サポートの受け方およびフィードバックをお寄せいただく方法のガイダンスについては、Office VBA のサポートおよびフィードバックを参照してください。