# 選択式

選択式のSELECT-FROM-WHEREからなる記述に基づいて、射影と絞込みにより表群から新たに表の値を得ることができます。

#### 構文

    SELECT [ DISTINCT | ALL ] 選択項目 [ , 選択項目]*
    FROM 節
    [ WHERE 節 ]
    [ GROUP BY 節 ]
    [ HAVING 節 ]

選択項目:

    {
        * |
        { 表名 | 相関名 } .* |
        式 [AS 単純列名 ]
    }

SELECT節には、式の一覧およびFROM節とWHERE節の結果に適用される数量詞があります。 DISTINCTが指定された場合、重複は取り除かれ同じ値を持つ行は一つしかありません。ここでNULL値同士は同じ値と扱われます。もし数量詞がないかALLなら、結果にて行の値が重複しても取り除かれません。(既定はALLなのです。)

選択項目により一つ以上の結果の列が、検索式で得られる結果の表に射影されます。

FROM節の記述により、節に書かれた項目の直積が結果として生成されます。さらにWHERE節により、その結果は限定されます。

WHERE節では真偽式に従い、行が絞り込まれます。式が真と評価された行だけが結果として返されます。

GROUP BY節により、一つあるいはそれ以上の列の間で同じ値を持つ行が分類されまとめられます。GROUP BY節は多くの場合、集約が併せて使われます。

GROUP BY節がある場合、SELECT節には集約か分類列だけ置くことができます。もし分類の列以外の列をSELECT節に起きたい場合、その列を集約式の中においてください。例を挙げます。

    -- 員数、部署番号(WORKDEPT)、部の平均賃金(SALARY)、
    -- をEMPLOYEEという表にある全ての部署毎に一覧する。
    -- 結果は部の平均賃金ごとに昇順で並べられる。
    SELECT WORKDEPT, AVG(SALARY)
         FROM EMPLOYEE
         GROUP BY WORKDEPT
         ORDER BY 1

GROUP BY節がないにもかかわらず、選択項目に副問い合わせにはない集約がある場合、問合せは暗黙に分類されます。そのとき表全体が一つに分類されます。

HAVING節に書かれた(WHERE節と同様の)検索条件より、分類された表が絞り込まれます。この検索条件は分類列あるいは可視である集約のみ参照することができます。HAVING節は表から分類された後の情報に適用されます。HAVING節が評価されて真であった場合、その行は残って以降の処理が行われます。一方でHAVING節が評価されて偽あるいはNULLであった場合、その行は破棄されます。もしHAVING節があるにもかかわらず、GROUP BY節がない場合、暗黙に表全体が一つに分類されます。

Derby は選択式を次の順番で処理します。

- FROM 節
- WHERE 節
- GROUP BY (または暗黙のGROUP BY)
- HAVING 節
- SELECT 節

選択式の結果は常に表です。

問合せにFROM節がない場合(表から情報を取得するのではなく、値を構成する場合)、選択式ではなく、VALUES式を使います。 例:

    VALUES CURRENT_TIMESTAMP

VALUES式を参照してください。

#### ワイルドカードの*

*によりFROM節にある表の全列が展開されます。

表名.* や 相関名.* により、その表の全列が展開されます。その表はFROM節になければなりません。

#### 列への命名

AS節を使って選択項目の列に名前をつける事ができます。もし選択項目が単なる列参照ではないかあるいは、AS節で名前がつけられていない場合、自動生成された名前が与えられます。

こういった列の名前は、さまざまな場合で便利に使うことができます。

- JDBCのResultSetMetaDataにて利用可能です。
- FROM節の副問い合わせにて、その選択式が使われた場合、結果表の列名として使われます。
- ORDER BY節にて並び替えを行う列の名前として使われます。

    -- この例はORDER BY節、表への相関名、
    -- SELECT-FROM-WHEREを示します。
    SELECT CONSTRAINTNAME, COLUMNNAME
    FROM SYS.SYSTABLES t, SYS.SYSCOLUMNS col,
    SYS.SYSCONSTRAINTS cons, SYS.SYSCHECKS checks
    WHERE t.TABLENAME = 'FLIGHTS' AND t.TABLEID = col.
    REFERENCEID AND t.TABLEID = cons.TABLEID
    AND cons.CONSTRAINTID = checks.CONSTRAINTID
    ORDER BY CONSTRAINTNAME
    -- この例はDISTINCT節の使い方を示します。
    SELECT DISTINCT ACTNO
    FROM EMP_ACT
    -- この例は式に名前を与える方法を示します。
    -- EMPLOYEEという表から、最も高い給料が他の全部署の給料の平均より安い部署の、
    -- 部署番号(WORKDEPT)、BOSSという名前を与えた部署の最も高い給料(SALARY)を
    -- 一覧します。
    SELECT WORKDEPT AS DPT, MAX(SALARY) AS BOSS
    	FROM EMPLOYEE EMP_COR
    	GROUP BY WORKDEPT
    	HAVING MAX(SALARY) < (SELECT AVG(SALARY)
    				FROM EMPLOYEE
    				WHERE NOT WORKDEPT = EMP_COR.WORKDEPT)
    	ORDER BY BOSS

親トピック: SQL式
関連概念
動的パラメータ
関連資料
TableExpression
VALUES式
式に関する優先順位
真偽式