SQL 解説書

全選択

>>-+-subselect---------+---------------------------------------->
   +-(fullselect)------+
   '-| values-clause |-'
 
      .---------------------------------------------------.
      V                                                   |
>--------+---------------------------------------------+--+----><
         '--+-   UNION------+---+-subselect---------+--'
            +-   UNION ALL--+   +-(fullselect)------+
            +-EXCEPT--------+   '-| values-clause |-'
            +-EXCEPT ALL----+
            +-INTERSECT-----+
            '-INTERSECT ALL-'
 
values-clause
 
              .-,------------------.
              V                    |
|---VALUES-------|  Values-row |---+----------------------------|
 
 Values-row
 
|---+--+-expression-+---------------+---------------------------|
    |  '-NULL-------'               |
    |    .-,-----------------.      |
    |    V                   |      |
    '-(------+-expression-+--+---)--'
             '-NULL-------'
 

全選択 (fullselect) は、選択ステートメント、 INSERT ステートメント、および CREATE VIEW ステートメントの構成要素の 1 つです。 また、これはステートメントの構成要素である特定の述部の構成要素ともなります。 述部の構成要素である全選択 は、 副照会 (subquery) と呼ばれます。 括弧で囲んだ全選択 (fullselect) は、 副照会と呼ばれることがあります。

セット演算子である UNION、EXCEPT、および INTERSECT は、 関係演算子の合併、差、積に対応しています。

全選択 は結果表を指定します。 集合演算子を使用しない全選択 の結果は、 指定した副選択または VALUES 文節の結果になります。

Values-clause
結果表の行の各列ごとに式を使用して実際の値を指定することによって、結果表を派生させます。 複数の行を指定することができます。

NULL は、複数の Values-row でのみ使用することができ、 同一列の少なくとも 1 行は NULL 以外でなければなりません (SQLSTATE 42826)。

Values-row は以下によって指定されます。

複数行からなる Values-clause には、 各 Values-row に同数の式が必要です (SQLSTATE 42826)。

次に、Values-clause の例とその意味を示します。

   VALUES (1),(2),(3)          - 3 rows of 1 column
   VALUES 1, 2, 3              - 3 rows of 1 column
   VALUES (1, 2, 3)            - 1 row of 3 columns
   VALUES (1,21),(2,22),(3,23) - 3 rows of 2 columns

Values-clause は、 n 個の Values-row RE1 〜 REn (n は 2 以上) で構成され、 以下と同等です。

   RE1 UNION ALL RE2 ... UNION ALL REn

これは、各 Values-row に対応する式は比較可能でなければならず (SQLSTATE 42825)、 結果のデータ・タイプは 結果のデータ・タイプに関する規則 に基づくことを意味しています。

UNION または UNION ALL
2 つの結果表 (R1 と R2) を組み合わせて、新たな結果表を導きます。 UNION ALL を指定すると、結果は R1 と R2 のすべての行から構成されるものになります。 ALL オプションなしで UNION を指定すると、 結果は R1 または R2 のいずれかの行すべての集合から、 重複行を除去したものになります。 しかしいずれにしても、UNION 表の各行は R1 か R2 のどちらかから取られた行です。

EXCEPT または EXCEPT ALL
2 つの結果表 (R1 と R2) を組み合わせて、新たな結果表を導きます。 EXCEPT ALL を指定すると、結果は、重複行の数を勘定に入れつつ、 R2 の中に対応する行のないすべての行で構成されるものになります。 ALL オプションなしで EXCEPT を指定すると、結果は、 それぞれの重複行を除去してから R1 にのみ存在する行を取り出したもので構成されます。

INTERSECT または INTERSECT ALL
2 つの結果表 (R1 と R2) を組み合わせて、新たな結果表を導きます。 INTERSECT ALL を指定すると、 結果は R1 と R2 の両方に含まれる行すべてで構成されるものになります。 ALL オプションなしで INTERSECT を指定すると、 結果は、R1 と R2 の両方にある行すべての集合から重複行を除去したものになります。

結果表 R1 の中の列の数と R2 の中の列の数は、 同じでなければなりません (SQLSTATE 42826)。 ALL キーワードを指定しない場合、R1 および R2 には、 255 バイトよりも大きいと宣言されたストリング列を含めてはなりません。 また、データ・タイプが LONG VARCHAR、LONG VARGRAPHIC、 BLOB、CLOB、DBCLOB、DATALINK であるストリング列や、 それらのタイプのいずれかを基にした特殊タイプ、 または構造タイプであるストリング列を含めることもできません (SQLSTATE 42907)。

結果の列の名前は、次のようになります。

生成された名前を調べるには、SQL ステートメントの DESCRIBE を実行して、 SQLNAME フィールドを参照します。

2 つの行が互いに重複していると言えるのは、 最初の行の各値が 2 番目の行の対応する値に等しい場合です。 (重複を判別する場合、2 つのヌル値は等しいものとみなされます)。

複数の演算を 1 つの式の中に結合した場合は、括弧内の演算が先に実行されます。 括弧がない場合、演算は左から右に実行されますが、例外として、 すべての INTERSECT 演算は UNION または EXCEPT の演算の前に実行されます。

次の例では、表 R1 と R2 の値を左端に示しています。 他にリストされている見出しは、R1 と R2 の種々のセット演算の結果の値を示しています。
R1 R2 UNION ALL UNION EXCEPT ALL EXCEPT INTER- SECT ALL INTER- SECT
1 1 1 1 1 2 1 1
1 1 1 2 2 5 1 3
1 3 1 3 2
3 4
2 3 1 4 2
4
2 3 1 5 4


2 3 2
5


3 4 2




4
2




4
3




5
3






3






3






3






4






4






4






5




結果列のデータ・タイプの判別の規則については、 結果のデータ・タイプに関する規則 を参照してください。

ストリング列の変換の処理方法の規則については、 ストリング変換に関する規則 を参照してください。

全選択の例

例 1: EMPLOYEE 表からすべての列と行を選択します。

    SELECT * FROM EMPLOYEE

例 2: EMPLOYEE 表の従業員で、 その部門番号 (WORKDEPT) が 'E' で始まる部門に属しているか、 またはプロジェクト番号 (PROJNO) が 'MA2100'、'MA2110'、 または 'MA2112' である EMP_ACT 表のプロジェクトに割り当てられている従業員すべての従業員番号 (EMPNO) をリストします。

  SELECT EMPNO
     FROM EMPLOYEE
     WHERE WORKDEPT LIKE 'E%'
  UNION
  SELECT EMPNO
     FROM EMP_ACT 
     WHERE PROJNO IN('MA2100', 'MA2110', 'MA2112')

例 3: 例 2 と同じ照会を行い、さらに EMPLOYEE 表の行には 'emp'、 EMP_ACT 表の行には 'emp_act' という "タグ" を付けます。 例 2 の結果とは異なり、この照会では、同じ EMPNO が複数回戻され、 付加される "タグ" によりどの表からとられたかが示されます。

  SELECT EMPNO, 'emp'
     FROM EMPLOYEE
     WHERE WORKDEPT LIKE 'E%'
  UNION
  SELECT EMPNO, 'emp_act' FROM EMP_ACT
     WHERE PROJNO IN('MA2100', 'MA2110', 'MA2112')

例 4: 例 2 と同じの照会を行いますが、重複行が除去されないように UNION ALL を使用します。

    SELECT EMPNO
      FROM EMPLOYEE  
     WHEREWORKDEPTLIKE 'E%'
  UNION ALL
  SELECT EMPNO 
     FROM EMP_ACT 
     WHERE PROJNO IN('MA2100', 'MA2110', 'MA2112')

例 5: 例 3 と同じ照会を行いますが、現在どの表にもない 2 人の従業員を追加して、 それらの行に "new" というタグを付けます。

    SELECT EMPNO, 'emp'
     FROM EMPLOYEE 
     WHEREWORKDEPTLIKE 'E%'
  UNION
  SELECT EMPNO, 'emp_act'
     FROM EMP_ACT
     WHERE PROJNO IN('MA2100', 'MA2110', 'MA2112')
  UNION
     VALUES ('NEWAAA', 'new'), ('NEWBBB', 'new')

例 6: この EXCEPT の例は、T1 に存在し、T2 に存在しない行をすべて生成します。

   (SELECT * FROM T1)
   EXCEPT ALL
   (SELECT * FROM T2)

NULL 値が含まれていない場合、この例は次の例と同じ結果を戻します。

      SELECT ALL *
      FROM T1
      WHERE NOT EXISTS (SELECT * FROM T2
                          WHERE T1.C1 = T2.C1 AND T1.C2 = T2.C2 AND...)

例 7: この INTERSECT の例は、表 T1 と T2 の両方にあるすべての行を生成し、 重複した行を除去します。

   (SELECT * FROM T1)
   INTERSECT
   (SELECT * FROM T2)

NULL 値が含まれていない場合、この例は次の例と同じ結果を戻します。

      SELECT DISTINCT * FROM T1
      WHERE EXISTS (SELECT * FROM T2
                          WHERE T1.C1 = T2.C1 AND T1.C2 = T2.C2 AND...)

ここで、C1、C2、などは T1 と T2 の列を表します。


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