Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

UNION

2 つ以上の SELECT 文を組み合わせます。

Synopsis

select-statement {UNION [ALL] [%PARALLEL] select-statement}

select-statement {UNION [ALL]  [%PARALLEL] (query)}

(query) {UNION [ALL]  [%PARALLEL] select-statement}

(query) {UNION [ALL]  [%PARALLEL] (query)}

引数

ALL オプション — キーワードのリテラル。指定した場合、重複するデータ値が返されます。省略した場合は、重複するデータ値が抑制されます。
%PARALLEL オプション%PARALLEL キーワード。指定した場合、UNION のそれぞれの側は、別個のプロセスとして並行して実行されます。
select-statement データベースからデータを検索する SELECT 文。
query 1 つまたは複数の SELECT 文を組み合わせるクエリ。

概要

UNION は 2 つ以上のクエリを単一のクエリに組み合わせ、1 つの結果にまとめられたデータを取り出します。UNION によって組み合わされたクエリは、単一の SELECT 文で構成される単純なクエリになるか、または複合クエリになります。

SELECT 文間で UNION を使用可能にするには、それぞれで指定される列の数が一致している必要があります。列数が異なる SELECT を指定すると、SQLCODE -9 エラーが発生します。1 つの SELECT 内に NULL 列を指定し、列数を一致させるために別の SELECT 内のデータ列と組み合わせることができます。NULL のこの使用法は、以下の “例” のセクションで紹介します。

Caution:

UNIONSELECT * 構文を使用するには、テーブルに同じ列数が含まれている必要があります。そのため、列を追加したり削除してテーブル定義を今後変更すると、このソートの集合において予期しないエラーが発生する可能性があります。

結果列名およびデータ型は、UNION クエリの最初の項の列名とデータ型から取得されます。2 つの項で対応する列の名前が同じでない場合、AS 節を使用して結果列を特定することをお勧めします。

一般の UNION では、重複する行 (すべての値が同一) が結果から削除されます。UNION ALL は、結果内の重複行を保持します。

UNION の結果の文字列フィールドには、対応する SELECT フィールドの照合タイプが指定されますが、フィールドを照合しても一致しない場合には、EXACT 照合が割り当てられます。

TOP 節と ORDER BY 節

UNION 文は、結果を順序付ける ORDER BY 節で終結させることができます。この ORDER BY は文全体に適用されるため、サブクエリではなく、クエリの一番外側の部分で使用する必要があります。TOP 節と組み合わせる必要はありません。以下の例では、ORDER BY のこの使用法を示します。2 つの SELECT 文でデータを選択し、そのデータを UNION によって結合してから、ORDER BY で結果を順序付けます。

SELECT Name,Home_Zip FROM Sample.Person
  WHERE Home_Zip %STARTSWITH 9
UNION
SELECT Name,Office_Zip FROM Sample.Employee
  WHERE Office_Zip %STARTSWITH 8
ORDER BY Home_Zip 

SELECT リストの列に対応しない列番号を ORDER BY で使用すると、SQLCODE -5 エラーが発生します。SELECT リストの列に対応しない列名を ORDER BY で使用すると、SQLCODE -6 エラーが発生します。

UNION での SELECT 文のどちらか (または両方) に ORDER BY 節を含めることができますが、TOP 節と組み合わせる必要があります。この ORDER BY は、どの行を TOP 節によって選択するかを決定するために適用されます。以下の例では、ORDER BY のこの使用法を示します。2 つの各 SELECT 文で ORDER BY を使用して、それらの行を順序付けます。これにより、上位行として選択する行を決定します。選択されたデータを UNION によって結合してから、最後の ORDER BY で結果を順序付けます。

SELECT TOP 5 Name,Home_Zip FROM Sample.Person
  WHERE Home_Zip %STARTSWITH 9
  ORDER BY Name
UNION
SELECT TOP 5 Name,Office_Zip FROM Sample.Employee
  WHERE Office_Zip %STARTSWITH 8
  ORDER BY Office_Zip
ORDER BY Home_Zip

TOP は、以下のように ORDER BY 節の位置に応じて、UNION の最初の SELECT に適用するか、UNION の結果に適用できます。

  • UNION の結果に TOP...ORDER BY を適用します。UNION を FROM 節のサブクエリに記述している場合、TOP と ORDER BY はその UNION の結果に適用されます。以下はその例です。

    SELECT TOP 10 Name,Home_Zip
      FROM (SELECT Name,Home_Zip FROM Sample.Person
              WHERE Name %STARTSWITH 'A'
            UNION
            SELECT Name,Home_Zip FROM Sample.Person
              WHERE Home_Zip %STARTSWITH 8)
    ORDER BY Home_Zip
    
  • TOP を最初の SELECT に適用し、ORDER BY を UNION の結果に適用します。以下はその例です。

    SELECT TOP 10 Name,Home_Zip 
      FROM Sample.Person
      WHERE Name %STARTSWITH 'A'
    UNION
    SELECT Name,Home_Zip FROM Sample.Person
      WHERE Home_Zip %STARTSWITH 8
    ORDER BY Home_Zip
    

囲みの括弧

UNION は、その SELECT 文の一方または両方、あるいは UNION 文全体を、オプションとして括弧で囲むことができます。1 組または複数組の括弧を指定できます。以下に示す括弧の使用は、すべて有効です。

(SELECT ...) UNION SELECT ...
(SELECT ...) UNION (SELECT ...)
((SELECT ...)) UNION ((SELECT ...))
(SELECT ... UNION SELECT ...)
((SELECT ...) UNION (SELECT ...))

使用する括弧の組ごとに、別個のクエリ・キャッシュが生成されます。

UNION/OR 最適化

既定では、適切な場合に、SQL 自動最適化は UNION サブクエリを OR 条件に変換します。この UNION/OR 変換により、EXISTS やその他の下位の述語を Caché クエリ・オプティマイザ・インデックスで使用できる最上位の条件に移行できます。この既定の変換は、ほとんどの状況に適しています。ただし、状況によってはこの UNION/OR 変換によって大幅なオーバーヘッドが生じることがあります。%NOUNIONOROPT クエリ最適化オプションを指定すると、この FROM 節に関連付けられた WHERE 節内のすべての条件に対する自動の UNION/OR 変換が無効になります。そのため、複雑なクエリでは、この自動 UNION/OR 最適化を 1 つのサブクエリに対してのみ無効にして、その他のサブクエリには有効にすることができます。%NOUNIONOROPT の詳細は、"FROM 節" を参照してください。

サブクエリに関係する条件が UNION に適用される場合、各 UNION の末尾ではなくオペランド内に適用されます。これにより、サブクエリ最適化を各 UNION オペランドで適用できます。サブクエリ最適化オプションについては、"FROM 節" を参照してください。以下の例では、WHERE 節の条件は、UNION の結果ではなく、UNION 内の各サブクエリに適用されます。

SELECT Name,Age FROM 
  (SELECT Name,Age FROM Sample.Person
   UNION SELECT Name,Age FROM Sample.Employee)
WHERE Age IN (SELECT TOP 5 Age FROM Sample.Employee WHERE Age>55 ORDER BY Age)

UNION ALL の集約の最適化

SQL による UNION ALL の自動最適化は、最上位の集約を UNION 範囲にプッシュします。これにより、%PARALLEL キーワードの有無に関係なく、パフォーマンスが大幅に向上します。以下に例を示します。

SELECT COUNT(*) FROM (SELECT item1 FROM table1 UNION ALL SELECT item2 FROM table2) 

これは、次のように最適化されます。

SELECT SUM(y) FROM (SELECT COUNT(*) AS y FROM table1 UNION ALL SELECT COUNT(*) AS y FROM table2) 

この最適化は、(COUNT だけでなく) 最上位のすべての集約関数に適用されます。これには、最上位の集約関数を複数持つクエリが含まれます。この最適化を適用するには、外側のクエリは WHERE や GROUP BY 節のない "1 行" のクエリであることが必要です。これは %VID を参照することはできず、UNION ALL が FROM 節内の唯一のストリームであることが必要です。集約は入れ子にすることはできません。また、使用されている集約関数では、%FOREACH() グループ化や DISTINCT は使用できません。

並列処理

%PARALLEL キーワードは、マルチプロセッサ・システムでの並列処理および分散処理をサポートします。これにより Caché は各クエリを同じマシン上の別個のプロセスに割り当て、UNION クエリに対して並列処理を実行します。場合によっては、この処理によりクエリが別のマシンに送信され、そこで処理されることもあります。これらの処理はパイプ経由で通信し、Caché はサブクエリの結果を保持する 1 つ以上の一時ファイルを作成します。メインの処理では、結果の行が結合され、最終結果が返されます。詳細は、UNION クエリの "プラン表示" を参照し、%PARALLEL キーワードを指定した場合と指定しない場合のプラン計画を比較してください。

一般に、各行の生成に費やす手間がかかるほど、%PARALLEL はより有用になります。

%PARALLEL キーワードを指定すると、自動の UNION から OR への最適化が無効になります。

以下の例では、%PARALLEL キーワードの使用法を示します。

SELECT Name FROM Sample.Employee WHERE Name %STARTSWITH 'A'
UNION %PARALLEL
SELECT Name FROM Sample.Person WHERE Name %STARTSWITH 'A'
ORDER BY Name
SELECT Name FROM Sample.Employee WHERE Name %STARTSWITH 'A'
UNION ALL %PARALLEL
SELECT Name FROM Sample.Person WHERE Name %STARTSWITH 'A'
ORDER BY Name

%PARALLEL は、SELECT クエリとそのサブクエリで使用するためのものです。INSERT コマンド・サブクエリは %PARALLEL を使用できません。

UNION クエリによっては、%PARALLEL キーワードの追加が不適切な場合もあり、それによってエラーが発生することもあります。OUTER JOIN、相関フィールド、サブクエリを含む IN 述語条件、コレクション述語といった SQL 構造は、通常 UNION %PARALLEL の実行をサポートしません。UNION %PARALLEL は FOR SOME 述部ではサポートされますが、FOR SOME %ELEMENT コレクション述部ではサポートされません。UNION クエリで %PARALLEL を正常に使用できるかどうかを判断するには、それぞれの UNION 範囲を個別にテストします。FROM %PARALLEL キーワードを追加して、それぞれの範囲のクエリを別々にテストしてください。FROM %PARALLEL クエリの 1 つで並列処理のないクエリ・プランが生成された場合、その UNION クエリは %PARALLEL をサポートしないことになります。

UNION ALL と集約関数

SQL 自動最適化では、UNION ALL 集約関数を UNION 範囲サブクエリにプッシュします。SQL は各サブクエリの集約値を計算してから、結果を結合し、元の集約値を返します。例えば、以下のようになります。

SELECT COUNT(Name) FROM (SELECT Name FROM Sample.Person
                    UNION ALL SELECT Name FROM Sample.Employee)

は、次のように最適化されます。

SELECT SUM(y) FROM (SELECT COUNT(Name) AS y FROM Sample.Person
                    UNION ALL SELECT COUNT(Name) AS y FROM Sample.Employee)

この結果、パフォーマンスが大幅に向上する場合があります。この最適化は、%PARALLEL キーワード付き、またはなしで適用されます。この最適化は複数の集約関数に適用されます。

この最適化の変換は、以下の状況でのみ発生します。

  • 外側のクエリの FROM 節には UNION ALL 文のみが含まれる必要がある。

  • 外側のクエリに WHERE 節または GROUP BY 節を含めることはできない。

  • 外側のクエリに %VID (ビュー ID) フィールドを含めることはできない。

  • 集約関数に DISTINCT または %FOREACH キーワードを含めることはできない。

  • 集約関数を入れ子にすることはできない。

以下の例は、2 つのテーブルのそれぞれで見つかったすべての Name に対応する行を持つ結果を生成しています。Name が両方のテーブルで見つかった場合、行が 2 つ作成されます。Name が従業員の場合、State としての "オフィス" という用語と従業員の役職とを連結して、オフィスの場所をリストします。Name が人の場合、State としての "自宅" という用語と役職に対する <null> とを連結して、自宅の場所をリストします。ORDER BY 節は結果を処理し、行の組み合わせは Name を使って順番に並べられます。

SELECT Name,Office_State||' office' AS State,Title 
FROM Sample.Employee
UNION
SELECT Name,Home_State||' home',NULL
FROM Sample.Person
ORDER BY Name

以下の 2 つの例は、ALL キーワードの効果を示しています。最初の例では、UNION は一意の値のみを返します。2 番目の例では、UNION ALL は重複する値を含むすべての値を返します。

SELECT Name
FROM Sample.Employee
WHERE Name %STARTSWITH 'A'
UNION
SELECT Name
FROM Sample.Person
WHERE Name %STARTSWITH 'A'
ORDER BY Name
SELECT Name
FROM Sample.Employee
WHERE Name %STARTSWITH 'A'
UNION ALL
SELECT Name
FROM Sample.Person
WHERE Name %STARTSWITH 'A'
ORDER BY Name

関連項目

FeedbackOpens in a new tab