SQL 概説

結合

複数の表のデータを組み合わせることを、「表を結合する」といいます。 データベース・マネージャーは、指定された表の行のすべての組み合わせを生成します。 各組み合わせごとに、 結合条件 が検査されます。 結合条件は、いくつかの制限を伴う検索条件です。 それらの制限のリストについては、 SQL 解説書 を参照してください。

結合条件に関係している列のデータ・タイプは、 同じものである必要はありませんが、 互換性のあるものでなければなりません。 結合条件は、他の検索条件と同じようにして評価され、 その比較操作には同じ規則が適用されます。

FROM 文節に指定されている表から取られた行が、互いに全く関係のないものであったとしても、 結合条件を指定しない場合には、そのすべての組み合わせが戻されます。 その結果は 2 つの表の直積 と呼ばれます。

この後に示す例は、次の 2 つの表に基づいています。 それらは、サンプル・データベースの表を簡略化したものですが、 サンプル・データベース内には存在していません。 それらは、結合一般に関係していることの概要を示すために使われています。 SAMP_STAFF の内容はパートとして雇われているわけではない従業員の名前とその肩書きのリストであり、 SAMP_PROJECT の内容は従業員 (パートとフルタイムの両方) の名前と担当するプロジェクトの名前のリストです。

それらの表は、以下のとおりです。

図 5. SAMP_PROJECT TABLE


REQTEXT

図 6. SAMP_STAFF TABLE


REQTEXT

次の例では、この 2 つの表の直積を生成しています。 結合条件を指定していないため、 行のすべての組み合わせが出力されます。

     SELECT SAMP_PROJECT.NAME, 
            SAMP_PROJECT.PROJ, SAMP_STAFF.NAME, SAMP_STAFF.JOB
        FROM SAMP_PROJECT, SAMP_STAFF

このステートメントの結果は、次のとおりです。

     NAME       PROJ   NAME       JOB
     ---------- ------ ---------- --------
     Haas       AD3100 Haas       PRES
     Thompson   PL2100 Haas       PRES
     Walker     MA2112 Haas       PRES    
     Lutz       MA2111 Haas       PRES    
     Haas       AD3100 Thompson   MANAGER 
     Thompson   PL2100 Thompson   MANAGER
     Walker     MA2112 Thompson   MANAGER 
     Lutz       MA2111 Thompson   MANAGER 
     Haas       AD3100 Lucchessi  SALESREP
     Thompson   PL2100 Lucchessi  SALESREP
     Walker     MA2112 Lucchessi  SALESREP
     Lutz       MA2111 Lucchessi  SALESREP
     Haas       AD3100 Nicholls   ANALYST 
     Thompson   PL2100 Nicholls   ANALYST 
     Walker     MA2112 Nicholls   ANALYST 
     Lutz       MA2111 Nicholls   ANALYST 

結合には、大きく分けて内部結合外部結合 の 2 種類があります。 ここまでに上げた例では、内部結合しか使っていません。 内部結合では、直積列のうち結合条件を満たすものだけが残されます。 一方の表には存在するがもう一方の表には存在しない行の情報は、 結果表に含められません。

次の例では、2 つの表の内部結合を生成しています。 内部結合では、フルタイムの従業員のうちプロジェクトに割り当てられている従業員が出力されます。

     SELECT SAMP_PROJECT.NAME, 
            SAMP_PROJECT.PROJ, SAMP_STAFF.NAME, SAMP_STAFF.JOB
        FROM SAMP_PROJECT, SAMP_STAFF
        WHERE SAMP_STAFF.NAME = SAMP_PROJECT.NAME

この内部結合は、次のようにも指定できます。

     SELECT SAMP_PROJECT.NAME, 
            SAMP_PROJECT.PROJ, SAMP_STAFF.NAME, SAMP_STAFF.JOB
        FROM SAMP_PROJECT INNER JOIN SAMP_STAFF
          ON SAMP_STAFF.NAME = SAMP_PROJECT.NAME

結果は、次のとおりです。

     NAME       PROJ   NAME       JOB
     ---------- ------ ---------- --------
     Haas       AD3100 Haas       PRES
     Thompson   PL2100 Thompson   MANAGER

内部結合の結果は、 右側の表と左側の表の NAME 列の値が一致している行で構成されています。 'Haas' と 'Thompson' の 2 人は、 フルタイム従業員の表 SAMP_STAFF に含まれており、 さらにプロジェクトに割り当てられているフルタイムとパートの従業員の表 SAMP_PROJECT にも含まれています。

外部結合は、左側の表の行と右側の表の行 (あるいはその両方に含まれる行) のうち、 内部結合には含まれない行と、内部結合とを連結したものです。 2 つの表の外部結合を実行する場合、 そのどちらか一方を左側の表、 他方を右側の表として割り当てることになります。 外部結合には、次の 3 種類のものがあります。

  1. 左外部結合。 これには、内部結合に加えて、 左側の表の行のうち内部結合に含まれないものが含まれます。
  2. 右外部結合。 これには、内部結合に加えて、 右側の表の行のうち内部結合に含まれないものが含まれます。
  3. 全外部結合。 これには、内部結合に加えて、 左側の表の行と右側の表の行のうち内部結合に含まれないものが含まれます。

表示する列を指定するには、SELECT ステートメントを使います。 FROM 文節の中で、 第 1 の表の名前の後に、LEFT OUTER JOIN、RIGHT OUTER JOIN、 または FULL OUTER JOIN のキーワードを指定します。 その後、第 2 の表と ON キーワードを指定します。 その ON キーワードの後に、 結合する表と表の間の関係を示す結合条件を指定します。

次の例では、SAMP_STAFF が右側の表、SAMP_PROJECT が左側の表です。 LEFT OUTER JOIN を使うことによって、 SAMP_PROJECT の中のすべての従業員 (フルタイムおよびパート) の名前 (NAME) とプロジェクト番号 (PROJ)、 およびフルタイムの従業員 (SAMP_STAFF に含まれる従業員) については肩書き (JOB) を出力します。

     SELECT SAMP_PROJECT.NAME, SAMP_PROJECT.PROJ,
            SAMP_STAFF.NAME, SAMP_STAFF.JOB
        FROM SAMP_PROJECT LEFT OUTER JOIN SAMP_STAFF
          ON SAMP_STAFF.NAME = SAMP_PROJECT.NAME

このステートメントの結果は、次のとおりです。

     NAME       PROJ                 NAME       JOB
     ---------- -------------------- ---------- --------------------
     Haas       AD3100               Haas       PRES
     Lutz       MA2111               -          -                   
     Thompson   PL2100               Thompson   MANAGER
     Walker     MA2112               -          -

すべての列に値が含まれている行は、内部結合の結果です。 それらは結合条件を満たす行です。 'Haas' と 'Thompson' の 2 人は、SAMP_PROJECT (左側の表) と SAMP_STAFF (右側の表) の両方に含まれています。 結合条件が満たされていない行については、 右側の表の列が NULL 値になっています。 'Lutz' と 'Walker' は、SAMP_PROJECT 表に含まれているパートの従業員であり、SAMP_STAFF 表には含まれていません。 結果セットには、 左側の表のすべての行が含まれていることに注意してください。

次の例では、SAMP_STAFF が右側の表、SAMP_PROJECT が左側の表です。 RIGHT OUTER JOIN を使うことによって、 SAMP_STAFF の中のすべてのフルタイム従業員の名前 (NAME) と肩書き (JOB)、 およびプロジェクトに割り当てられている従業員 (SAMP_PROJECT に含まれる従業員) についてはそのプロジェクト番号 (PROJ) を出力します。

     SELECT SAMP_PROJECT.NAME, 
            SAMP_PROJECT.PROJ, SAMP_STAFF.NAME, SAMP_STAFF.JOB
        FROM SAMP_PROJECT RIGHT OUTER JOIN SAMP_STAFF
          ON SAMP_STAFF.NAME = SAMP_PROJECT.NAME

結果は、次のとおりです。

    NAME       PROJ                 NAME       JOB
    ---------- -------------------- ---------- --------------------
    Haas       AD3100               Haas       PRES
    -          -                    Lucchessi  SALESREP
    -          -                    Nicholls   ANALYST
    Thompson   PL2100               Thompson   MANAGER             

左外部結合の場合と同じように、 すべての列に値が含まれている行は、内部結合の結果です。 それらは結合条件を満たす行です。 'Haas' と 'Thompson' の 2 人は、SAMP_PROJECT (左側の表) と SAMP_STAFF (右側の表) の両方に含まれています。 結合条件が満たされていない行については、 左側の表の列が NULL 値になっています。 'Lucchessi' と 'Nicholls' は、プロジェクトに割り当てられていないフルタイムの従業員です。 その 2 人は SAMP_STAFF には含まれていますが、SAMP_PROJECT には含まれていません。 結果セットには、 右側の表のすべての行が含まれていることに注意してください。

次の例では、SAMP_PROJECT 表と SAMP_STAFF 表に対して、FULL OUTER JOIN を使っています。 これにより、 フルタイム (プロジェクトに割り当てられていない人も含む) の従業員とパートの従業員のすべての名前が出力されます。

     SELECT SAMP_PROJECT.NAME, SAMP_PROJECT.PROJ,
            SAMP_STAFF.NAME, SAMP_STAFF.JOB
        FROM SAMP_PROJECT FULL OUTER JOIN SAMP_STAFF
          ON SAMP_STAFF.NAME = SAMP_PROJECT.NAME

結果は、次のとおりです。

     NAME       PROJ                 NAME       JOB
     ---------- -------------------- ---------- --------------------
     Haas       AD3100               Haas       PRES
     -          -                    Lucchessi  SALESREP
     -          -                    Nicholls   ANALYST
     Thompson   PL2100               Thompson   MANAGER
     Lutz       MA2111               -          -
     Walker     MA2112               -          -

この結果には、左外部結合、右外部結合、 および内部結合が含まれています。 フルタイムとパートのすべての従業員が含まれています。 左外部結合および右外部結合の場合のように、 結合条件が満たされていない値については、 それぞれ該当する列が NULL 値になっています。 結果セットには、SAMP_STAFF と SAMP_PROJECT のすべての行が含まれています。


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]