問合せ

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

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')