問合せ UNIONUNION ALL

問合せにより、既存表や表に組込みの定数を基にして、仮想的な表が作られます。

Syntax{ ( Query ) | Query INTERSECT [ ALL | DISTINCT ] Query | Query EXCEPT [ ALL | DISTINCT ] Query | Query UNION [ ALL | DISTINCT ] Query | 選択式 | VALUES式 }

問合せの前後に任意で括弧を置くことができます。また、INTERSECT、EXCEPT、UNION演算子の評価順を括弧を使って変えることができます。INTERSECTを除きこれらの演算子は、括弧がなければ左から右に評価されます。INTERSECTはUNIONあるいはEXCEPTより前に評価されます。

UNION、INTERSECT、EXCEPT ALLにおける結果の重複

ALLとDISTINCTというキーワードにより処理結果から重複を取り除くか否かが決まります。 DISTINCTというキーワードがあれば、結果に重複行はありません。ALLというキーワードがあれば、入力によって結果に重複行がある場合があります。既定はDISTINCTなので、ALLかDISTINCTか指定しなければ重複は取り除かれます。例えばUNIONの場合は、両方の問合せの全行を元に一時的なResultSetを生成したのち、重複行を取り除いてから結果を返します。これがUNION ALLならば、両方の問合せの全行が返されます。

左表にある重複した行の数をL、右表にある左表と同じ内容で重複した行の数をRとすると、どの操作を行うかにより、結果表にある重複した行の数は次のようにきまります。(ALLが指定されたとします。)

  • UNION: ( L + R )。
  • EXCEPT: ( L – R )と0(零)のうち大きいほう
  • INTERSECT: LとRのうち小さいほう

-- 選択式 SELECT * FROM ORG -- 副問合せ SELECT * FROM (SELECT CLASS_CODE FROM CL_SCHED) AS CS -- 副問合せ SELECT * FROM (SELECT CLASS_CODE FROM CL_SCHED) AS CS (CLASS_CODE) -- UNIONにより -- ORGという表にある全行の -- DEPTNUMBとMANAGERという列に加え、 -- (1,2)と(3,4)を返す。 -- なお、DEPTNUMBとMANAGERはsmallint型の列である。 SELECT DEPTNUMB, MANAGER FROM ORG UNION ALL VALUES (1,2), (3,4) -- 値の式 VALUES (1,2,3) -- EMPLOYEEという表にて部署番号(WORKDEPT)が'E'で始まる社員および、 -- EMP_ACTという表にてプロジェクト番号(PROJNO)が -- 'MA2100'、'MA2110'あるいは'MA2112'のプロジェクトにアサインされている社員の -- 社員番号(EMPNO)を一覧する。 SELECT EMPNO FROM EMPLOYEE WHERE WORKDEPT LIKE 'E%' UNION SELECT EMPNO FROM EMP_ACT WHERE PROJNO IN('MA2100', 'MA2110', 'MA2112') -- 前の例と同じ内容の問合せを行い、EMPLOYEEという表から得た行には'emp'、 -- EMP_ACTという表から得た行には'emp_act'という"タグ"をつける。 -- どちらの表から来たかをあらわす"タグ"があるので、 -- この問合せは前の問合せとは違い、同じEMPNOを一回より多く返すことがある。 SELECT EMPNO, 'emp' FROM EMPLOYEE WHERE WORKDEPT LIKE 'E%' UNION SELECT EMPNO, 'emp_act' FROM EMP_ACT WHERE PROJNO IN('MA2100', 'MA2110', 'MA2112') -- 前の例とほぼ同じ内容の問合せである。 -- UNION ALLが指定されたので重複は取り除かれなくなる。 SELECT EMPNO FROM EMPLOYEE WHERE WORKDEPT LIKE 'E%' UNION ALL SELECT EMPNO FROM EMP_ACT WHERE PROJNO IN('MA2100', 'MA2110', 'MA2112') -- 前の例とほぼ同じ内容の問合せである。 -- いずれの表にもいない二人の社員を加えて、 -- その行に"new"というタグをつけた。 SELECT EMPNO, 'emp' FROM EMPLOYEE WHERE WORKDEPT LIKE 'E%' UNION SELECT EMPNO, 'emp_act' FROM EMP_ACT WHERE PROJNO IN('MA2100', 'MA2110', 'MA2112') UNION VALUES ('NEWAAA', 'new'), ('NEWBBB', 'new')