PostgreSQL 8.0.0 文書
前のページ | 巻戻し |  | 早送り | 次のページ

# SELECT

## 名前

SELECT -- テーブルもしくはビューからの行の検索

## 概要

    SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
        * | expression [ AS output_name ] [, ...]
        [ FROM from_item [, ...] ]
        [ WHERE condition ]
        [ GROUP BY expression [, ...] ]
        [ HAVING condition [, ...] ]
        [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]
        [ ORDER BY expression [ ASC | DESC | USING operator ] [, ...] ]
        [ LIMIT { count | ALL } ]
        [ OFFSET start ]
        [ FOR UPDATE [ OF table_name [, ...] ] ]

    ここでfrom_itemは以下のいずれかです。

        [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
        ( select ) [ AS ] alias [ ( column_alias [, ...] ) ]
        function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ]
        function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )
        from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]

## 説明

`SELECT`は1つ以上のテーブルから行を返します。 `SELECT`の一般的な処理は以下の通りです。

1. `FROM`リストにある全要素が計算されます。 (`FROM`リストの各要素は実テーブルか仮想テーブルです。) `FROM`リストに複数の要素が指定された場合、それらはクロス結合されます。 (後述のFROM 句を参照してください。)

2. `WHERE`句が指定された場合、条件を満たさない行は全て出力から取り除かれます。 (後述のWHERE 句を参照してください。)

3. `GROUP BY`句が指定された場合、出力は、1つ以上の値に一致する行のグループに分割されます。 `HAVING`句が指定された場合、指定した条件を満たさないグループは取り除かれます。 (後述のGROUP BY 句とHAVING 句を参照してください。)

4. 実際の出力行は、選択された各行に対して、`SELECT`出力式を使用して計算されたものです。 (後述のSELECT リストを参照してください。)

5. `UNION`、`INTERSECT`、および、`EXCEPT`演算子を使用すると、複数の`SELECT`文の出力を1つの結果集合にまとめることができます。 `UNION`演算子は、両方あるいは片方の結果集合に存在する行を全て返します。 `INTERSECT`演算子は両方の結果集合に存在する行を全て返します。 `EXCEPT`演算子は最初の結果集合にあり、2番目の結果集合に無い行を返します。 `ALL`が指定されない限り、これら3つとも、重複する行は取り除かれます。 (後述のUNION 句、INTERSECT 句、および、EXCEPT 句を参照してください。)

6. `ORDER BY`句が指定された場合、返される行は指定した順番でソートされます。 `ORDER BY`が指定されない場合は、システムが計算過程で最初に見付けたものという何らかの順番で行が返されます。 (後述のORDER BY 句を参照してください。)

7. `DISTINCT`は結果から重複行を取り除きます。 `DISTINCT ON`は、指定された式全てに一致する行を取り除きます。 (デフォルトの)`ALL`は重複した行も含め、全ての候補行を返します。 (後述のDISTINCT 句を参照してください。)

8. `LIMIT`あるいは`OFFSET`句が指定された場合、`SELECT`文は結果行の一部分のみを返します。 (後述のLIMIT 句を参照してください。)

9. `FOR UPDATE`句により、`SELECT`文は、引続き実行される更新用に選択行をロックします。 (後述のFOR UPDATE 句を参照してください。)

テーブルから値を読み取るためには`SELECT`権限が必要です。 `FOR UPDATE`を使用するためには、同様に`UPDATE`権限が必要です。

## パラメータ

### `FROM` 句

`FROM`句は`SELECT`の対象となるソーステーブルを1つ以上指定します。 複数のソースが指定された場合、結果は全てのソースの直積(クロス結合)となります。 しかし、通常は直積の小さな一部分を返すように制限するために制約条件が付け加えられます。

`FROM`句には以下の要素を指定できます。

`table_name`

  既存のテーブルもしくはビューの名前です(スキーマ修飾名でも可)。 `ONLY`が指定された場合、そのテーブルのみがスキャンされます。 もし `ONLY`が指定されない場合、テーブルと(もしあれば)それを継承する全てのテーブルがスキャンされます。 子テーブルがスキャンされることを表すために、テーブル名に`*`を付けることができますが、現在のバージョンでは、子テーブルのスキャンはデフォルトで行われます。 (7.1より前のリリースでは、`ONLY`がデフォルトでした。) デフォルトの振舞いを変更するには、sql_inheritance設定オプションを変更します。

`alias`

  別名を含む`FROM`アイテムの代替名です。 別名は簡潔さのため、もしくは自己結合(同じテーブルが複数回スキャンされる場合です)の曖昧さをなくすために使われます。 別名が指定されている場合は、その別名によって実際のテーブル名または関数名が完全に隠されます。 例えば、`FROM foo AS f`と指定されている場合、以降の`SELECT`文ではこの`FROM`アイテムを`foo`ではなく`f`として参照する必要があります。 テーブルの別名があれば、そのテーブルの複数の列の名前を置き換える列の別名リストを記述することができます。

`select`

  副`SELECT`は`FROM`句で使うことができます。 これは、その出力がこの`SELECT`コマンド実行時に一時テーブルとして作成されたかのように動作します。 副`SELECT`は括弧で囲まれなければならず、必ず別名が提供されなければなりません。

`function_name`

  `FROM`句に関数呼び出しを使用することができます。 (これは特に関数が結果セットを返す場合に有用なものですが、任意の関数を使用することができます。) これは、その出力がこの`SELECT`コマンド実行時に一時テーブルとして作成されたかのように動作します。 また、別名を使用することもできます。 別名があれば、その関数の複合戻り型の複数の属性の代替名を提供する別名リストを記述することができます。 関数が`record`データ型を返すものと定義されている場合は、別名すなわち`AS`キーワードとそれに続く`( `column_name` `data_type` [, ... ])`という形式の列定義リストが必要です。 列定義リストは、関数によって返される実際の列の数およびデータ型に一致していなければなりません。

`join_type`

  以下のいずれかです。

  - `[ INNER ] JOIN`

  - `LEFT [ OUTER ] JOIN`

  - `RIGHT [ OUTER ] JOIN`

  - `FULL [ OUTER ] JOIN`

  - `CROSS JOIN`

  `INNER`、および、`OUTER`結合型では、結合条件、すなわち、`NATURAL`, `ON `join_condition``、もしくは、`USING (`join_column` [, ...])`のいずれかを1つのみ指定する必要があります。 意味は後で説明します。 `CROSS JOIN`では、これらの句を記述しなくても構いません。

  `JOIN`句は、2つの`FROM`アイテムを結び付けます。 入れ子の順番を決めるために、必要ならば括弧を使用してください。 括弧が無いと、`JOIN`は左から右へと入れ子にされます。 どのような場合でも`JOIN`は、カンマで分けられた`FROM`項目よりも強く結び付きます。

  `CROSS JOIN`と`INNER JOIN`は、`FROM`の最上位で2つの項目を付けた結果と同一の、1つの直積を生成します。 しかし、(もしあれば)結合条件で制限をかけることができます。 `CROSS JOIN`は`INNER JOIN ON (true)`と等価であり、条件によって削除される行はありません。 これらの結合型は記述上の便宜のためだけのものです。 従って、通常の`FROM`と`WHERE`を行わないと何も行いません。

  `LEFT OUTER JOIN`は条件に合う直積の全ての行(つまり、その結合条件を満たす全ての組み合わされた行)に加え、右側の行を持たないが結合条件を満たす左側のテーブルの各々の行のコピーを返します。 この左側の行は右側の行にNULL値を挿入することで結合されたテーブルの全幅に拡張されます。 どの行がマッチしているかを決める間、`JOIN`句自身の条件のみが考慮されることに注意してください。 他の外部結合条件は後で適用されます。

  逆に、`RIGHT OUTER JOIN`は全ての結合された行と、それぞれの当てはまるものがなかった右側の行(左側はNULLで拡張されています)に一行ずつを返します。 左と右の入力を入れ換えることで`LEFT OUTER JOIN`に変換することもできるため、これはただの記述上の便宜でしかありません。

  `FULL OUTER JOIN`は、全ての結合された行、一致しなかった左側の行(を右側をNULLで拡張させた行)を1行ずつ、更に、一致しなかった右側の行(を左側をNULLで拡張させた行)を1行ずつ返します。

`ON `join_condition``

  `join_condition`は、結合においてどの行が一致したとみなすかどうかを指定する(`WHERE`句同様)`boolean`型の値を返す式です。

`USING (`join_column` [, ...])`

  `USING ( a, b, ... )`句は`ON left_table.a = right_table.a AND left_table.b = right_table.b ...`の省略形です。 `USING`は等価となる列の組合せの両方ではなく片方のみが結合の出力に含まれることを意味します。

`NATURAL`

  `NATURAL`は2つのテーブル内の同じ名前を持つ全てを指定した`USING`リストの省略形です。

### `WHERE` 句

省略可能な`WHERE`句は通常以下の形式となります。

    WHERE condition

ここで、`condition`は、評価の結果`boolean`型を返す任意の式です。 この条件を満たさない行は全て出力から取り除かれます。 全ての変数参照に実際の行の値を代入した時に式が真を返す場合に、行は条件を満たします。

### `GROUP BY` 句

省略可能な`GROUP BY`句は通常以下の形式となります。

    GROUP BY expression [, ...]

`GROUP BY`は、グループ化式で同じ値を共有する全ての行を1つの行に凝縮します。 `expression`は、入力列名か、出力列(`SELECT`リスト項目)の名前もしくは序数、もしくは、入力列の値から計算される任意の式を取ることができます。 曖昧な場合、`GROUP BY`の名前は出力列名ではなく入力列名として解釈されます。

集約関数がもし使用されていると、各グループを生成する全ての行に対して計算され、グループ毎に分けた値が生成されます。 (一方`GROUP BY`が無い場合は、集約関数は全ての選択された行に対して計算され、1つの値を生成します。) `GROUP BY`があると、集約関数内部以外でグループ化されていない列を参照する`SELECT`リストは無効になります。 グループ化されていない列について返される値は複数の値になってしまうからです。

### `HAVING` 句

省略可能な`HAVING`は通常以下の形になります。

    HAVING condition

ここで`condition`は`WHERE`句で指定するものと同じです。

`HAVING`はこの条件を満たさないグループ化された行を取り除きます。 `HAVING`は`WHERE`とは違います。 `WHERE`では、`GROUP BY`の適用前に、個別の行に対してフィルタを行い、`HAVING`は`GROUP BY`で生成されたグループ化された行に対してフィルタを行います。 `condition`内の列参照は、集約関数内で表れる参照を除き、曖昧さが無いグループ化された列を参照しなければなりません。

### `SELECT` リスト

`SELECT`リスト(`SELECT`と`FROM`の間にあるキーワード)は、`SELECT`文の出力行を形成する式を指定したものです。 この式では、`FROM`句内で計算された列を参照することができます(そして、通常は参照します)。 `AS `output_name``を使用して、出力列とは別の名前を指定できます。 この名前は主に表示用の列ラベルとして使われます。 また、`ORDER BY`と`GROUP BY`句内で列の値を参照するためにも使用されます。 しかし、`WHERE`や`HAVING`句では使用されず、ここには式を書かなければなりません。

式の代わりに、選択された行の全ての列を表す省略形として、出力リストに`*`と書くことができます。 また、そのテーブルのみに由来する列を表す省略形として、``table_name`.*`と書くこともできます。

### `UNION` 句

`UNION`は通常以下の形式となります。

    select_statement UNION [ ALL ] select_statement

`select_statement`は、`ORDER BY`、`LIMIT`、`FOR UPDATE`句を持たない、任意の`SELECT`文です。 (もし括弧で括られていたら、`ORDER BY`と`LIMIT`は副式に付与できます。 括弧が無いと、これらの句は右側の入力式にではなく、`UNION`の結果に対して適用されてしまいます。)

`UNION`演算子は、呼び出された`SELECT`文で返される行の和集合を計算します。 少なくともどちらか片方に表れれば、その行は2つの結果セットの和集合内にあります。 直接`UNION`の演算項目となる`SELECT`文は、同じ列数を返さなければならず、また、対応する列のデータ型には互換性が必要です。

`ALL`オプションが指定されていないと、`UNION`の結果には重複行は含まれません。 `ALL`は重複除去を行いません。 (従って、通常`UNION ALL`は`UNION`よりかなり高速です。 できるだけ`ALL`を使用してください。)

一つの`SELECT`文で複数の`UNION`演算子がある場合、括弧で示されない限り、その評価は左から右に行われます。

現時点では、`FOR UPDATE`を`UNION`の結果に対しても、`UNION`の何らかの入力に対しても指定することができません。

### `INTERSECT` 句

`INTERSECT`は通常以下の形式となります。

    select_statement INTERSECT [ ALL ] select_statement

`select_statement`は、`ORDER BY`、`LIMIT`、`FOR UPDATE`を持たない、任意の`SELECT`文です。

`INTERSECT`は、呼び出される`SELECT`文が返す行の積集合を計算します。 両方の結果セットに現れる場合、その行は2つの結果セットの積集合内に存在します。

`ALL`オプションが指定されていないと、`INTERSECT`の結果には重複行は含まれません。 `ALL`がある場合、左側テーブルに`m`個の重複、右側テーブルに`n`個の重複がある行は、結果セットにmin(`m`,`n`)個出現します。

一つの`SELECT`文で複数の`INTERSECT`演算子がある場合、括弧で示されない限り、その評価は左から右に行われます。 `INTERSECT`は`UNION`よりも強い結び付きです。 つまり、`A UNION B INTERSECT C` は`A UNION (B INTERSECT C)`と解釈されます。

現時点では、`FOR UPDATE`を`INTERSECT`の結果に対しても、`INTERSECT`の何らかの入力に対しても指定することができません。

### `EXCEPT` 句

`EXCEPT`は通常以下の形式となります。

    select_statement EXCEPT [ ALL ] select_statement

`select_statement`は、`ORDER BY`、`LIMIT`、`FOR UPDATE`句を持たない、任意の`SELECT`文です。

`EXCEPT`は、左側の`SELECT`文の結果に存在し、右側の結果には存在しない行の集合を計算します。

`ALL`オプションが指定されていないと、`EXCEPT`の結果には重複行は含まれません。 `ALL`がある場合、左側テーブルに`m`個の重複、右側テーブルに`n`個の重複がある行は、結果セットにmax(`m`-`n`,0)個出現します。

一つの`SELECT`文で複数の`EXCEPT`演算子がある場合、括弧で示されない限り、その評価は左から右に行われます。 `EXCEPT`の結び付きのレベルは`UNION`と同じです。

現時点では、`FOR UPDATE`を`EXCEPT`の結果に対しても、`EXCEPT`の何らかの入力に対しても指定することができません。

### `ORDER BY` 句

省略可能な`ORDER BY`句は通常以下の形式となります。

    ORDER BY expression [ ASC | DESC | USING operator ] [, ...]

`expression`には、出力列(`SELECT`リスト項目)の名前もしくは序数、あるいは、入力列値から形成される任意の式をとることができます。

`ORDER BY`句により、結果の行を指定した式に従ってソートすることができます。 もっとも左にある式で2つの行が等しくなった場合は、次の式に従い、それも等しければ更に次の式に進みます。 指定した式の全てで等しくなった場合は、実装に依存した順番で返されます。

序数とは、結果列の(左から右への)順序の位置です。 この機能により、一意な名前を持たない列に対して順序を定義することができます。 `AS`句を使用すれば結果列に名前を割り当てることができますので、これは決して必要なものではありません。

また、`ORDER BY`句には、`SELECT`結果リストに出現しない列を含む、任意の式を使用できます。 従って、以下の文は有効なものです。

    SELECT name FROM distributors ORDER BY code;

この機能の制限は、`UNION`、`INTERSECT`、`EXCEPT`の結果に`ORDER BY`を適用する場合は、式を使用できず、出力列の名前か序数のみを指定できるという点です。

`ORDER BY`式が、結果列名と入力列名の両方に一致する単なる名前であった場合、`ORDER BY`は結果列名としてそれを扱います。 これは、同じ状況における`GROUP BY`の選択とは反対です。 標準SQLとの互換性のためこの不整合が発生しています。

省略可能なキーワード`ASC`(昇順)、`DESC`(降順)を`ORDER BY`中の任意の式の後に付け加えることができます。 指定がなければ、デフォルトで`ASC`が付いているものとして扱われます。 別方法に、順序指定演算子名を`USING` 句に指定することができます。 通常、`ASC`は`USING <`と、`DESC`は`USING >`と同じです。 (しかし、ユーザ定義のデータ型の作者は、デフォルトのソート順が何かを正しく定義することができ、演算子に異なる名前を対応付けすることもできます。)

NULL値は他の値よりも高いものとしてソートされます。 言い替えると、昇順のソート順ではNULL値は最後に、降順のソート順ではNULL値は最初にソートされます。

文字型のデータでは、データベースクラスタの初期化時に決定されるロケール指定の照合順に従ってソートされます。

### `DISTINCT` 句

`DISTINCT`が指定されると、重複する行は全て結果セットから削除されます。 (各重複行の中で1行のみが保持されます。) `ALL`はこの反対のことを指定し、全ての行が保持されます。 これがデフォルトです。

`DISTINCT ON ( `expression` [, ...] )`は各行集合の中で与えられた式が等しいと評価した、最初の行のみを保持します。 `DISTINCT ON`式は、(上述の)`ORDER BY`と同じ規則で扱われます。 各集合の"最初の行"は、`ORDER BY`を使用して目的の行が最初に現れることを保証しない限り予測することはできません。 例えば、

    SELECT DISTINCT ON (location) location, time, report
        FROM weather_reports
        ORDER BY location, time DESC;

は、各地点の最新の気象情報を取り出します。 しかし、`ORDER BY`を使用して各地点の時間値を降順に強制しなかったとしたら、各地点の予測できない時間の予報を得ることになります。

`DISTINCT ON`式は`ORDER BY`式の最も左側に一致しなければなりません。 `ORDER BY`句は通常、各`DISTINCT ON`グループの中で希望する行の優先順位を決定する、追加的な式を含みます。

### `LIMIT` 句

`LIMIT`句は2つの独立した副句から構成されます。

    LIMIT { count | ALL }
    OFFSET start

`count`は返される行の最大数を指定し、一方、`start`は行を返し始める前に飛ばす行数を指定します。 両方とも指定された場合、`start`行が飛ばされ、そこから数えて`count`行が返されます。

`LIMIT`を使う時は、結果の行を一意な順番に強制する`ORDER BY`句を使うのが良い考えです。 そうしないと、問い合わせの行の予測不可能なサブセットを得ることになります。 10から20行目までを出そうとしているかもしれませんが、どの順番の10から20行目までなのでしょうか? `ORDER BY`を指定しない限りどの順番なのか分からないのです。

問い合わせプランナは問い合わせ計画を作成する時に`LIMIT`を考慮しますので、`LIMIT`と`OFFSET`に何を使用するかによって(異なる行の順番を生む)異なった計画を得ることになるでしょう。 従って、問い合わせの、異なるサブセットを選択するために異なる`LIMIT`/`OFFSET`の値を使うと、`ORDER BY`で予測可能な結果の順序を強制しない限り、矛盾した結果を返します。 これはバグではありません。 これは、SQLが`ORDER BY`で順番を制御しない限り、問い合わせの結果を特定の順番で返すことを約束しないという事実の本質的な結果なのです。

### `FOR UPDATE` 句

`FOR UPDATE`は以下の形式となります。

    FOR UPDATE [ OF table_name [, ...] ]

`FOR UPDATE`を使用すると、問い合わせによって検索された行が更新用にロックされます。 これにより、現行のトランザクションが終了するまでは、これらの行が他のトランザクションによって変更されたり削除されたりすることがなくなります。 つまり、現行のトランザクションが終了するまでは、他のトランザクションがこれらの行に対して`UPDATE`、`DELETE`、または、`SELECT FOR UPDATE`を試行しても拒否されるのです。 また、他のトランザクションからの`UPDATE`、`DELETE`、または、`SELECT FOR UPDATE`によって選択されている行がロックされている場合に`SELECT FOR UPDATE`を実行しようとすると、`SELECT FOR UPDATE`はそのトランザクションが終了するのを待ち、その後更新された行をロックして返します (行が削除された場合は返しません)。 詳細は第12章を参照してください。

`FOR UPDATE`内に特定のテーブルが指定されている場合は、そのテーブルの行のみがロックされ、`SELECT`内の他のテーブルは通常通りに読み込まれるだけです。

`FOR UPDATE`は、返される行が対応する個々のテーブル行を明確に識別できない場合には使用することができません。 例えば、集約には使用できません。

`FOR UPDATE`は、バージョン 7.3より前のPostgreSQLとの互換性のために`LIMIT`の前に書くことができます。 しかし、その場合でも実際には`LIMIT`の後に実行されるので、`LIMIT`の後に書くことをお勧めします。

## 例

`films`テーブルを`distributors`テーブルと結合します。

    SELECT f.title, f.did, d.name, f.date_prod, f.kind
        FROM distributors d, films f
        WHERE f.did = d.did

           title       | did |     name     | date_prod  |   kind
    -------------------+-----+--------------+------------+----------
     The Third Man     | 101 | British Lion | 1949-12-23 | Drama
     The African Queen | 101 | British Lion | 1951-08-11 | Romantic
     ...

全ての映画の`len`列を合計し`kind`列によって結果をグループ化します。

    SELECT kind, sum(len) AS total FROM films GROUP BY kind;

       kind   | total
    ----------+-------
     Action   | 07:34
     Comedy   | 02:58
     Drama    | 14:28
     Musical  | 06:42
     Romantic | 04:38

全ての映画の`len`列を合計し`kind`列によって結果をグループ化し、合計が5時間より少ないグループの合計を表示します。

    SELECT kind, sum(len) AS total
        FROM films
        GROUP BY kind
        HAVING sum(len) < interval '5 hours';

       kind   | total
    ----------+-------
     Comedy   | 02:58
     Romantic | 04:38

以下の二つの例は個別の結果を二番目の列(`name`)の内容に基づいてソートする、同じ方法です。

    SELECT * FROM distributors ORDER BY name;
    SELECT * FROM distributors ORDER BY 2;

     did |       name
    -----+------------------
     109 | 20th Century Fox
     110 | Bavaria Atelier
     101 | British Lion
     107 | Columbia
     102 | Jean Luc Godard
     113 | Luso films
     104 | Mosfilm
     103 | Paramount
     106 | Toho
     105 | United Artists
     111 | Walt Disney
     112 | Warner Bros.
     108 | Westward

次の例は、結果をそれぞれのテーブルでWで始まるものだけに制限して、どのように`distributors`テーブルと`actors`テーブルの結合を獲得するかを表しています。 重複しない行のみが必要なので、`ALL`キーワードは省略されています。

    distributors:               actors:
     did |     name              id |     name
    -----+--------------        ----+----------------
     108 | Westward               1 | Woody Allen
     111 | Walt Disney            2 | Warren Beatty
     112 | Warner Bros.           3 | Walter Matthau
     ...                         ...

    SELECT distributors.name
        FROM distributors
        WHERE distributors.name LIKE 'W%'
    UNION
    SELECT actors.name
        FROM actors
        WHERE actors.name LIKE 'W%';

          name
    ----------------
     Walt Disney
     Walter Matthau
     Warner Bros.
     Warren Beatty
     Westward
     Woody Allen

この例は、`FROM`句内での関数の使用方法を、列定義リストがある場合と無い場合の両方に関して示しています。

    CREATE FUNCTION distributors(int) RETURNS SETOF distributors AS $$
        SELECT * FROM distributors WHERE did = $1;
    $$ LANGUAGE SQL;

    SELECT * FROM distributors(111);
     did |    name
    -----+-------------
     111 | Walt Disney

    CREATE FUNCTION distributors_2(int) RETURNS SETOF record AS $$
        SELECT * FROM distributors WHERE did = $1;
    $$ LANGUAGE SQL;

    SELECT * FROM distributors_2(111) AS (f1 int, f2 text);
     f1  |     f2
    -----+-------------
     111 | Walt Disney

## 互換性

当然ながら、`SELECT`文は標準SQLと互換性があります。 しかし、拡張機能や実現されていない機能もいくつかあります。

### `FROM` 句の省略

PostgreSQLでは、`FROM`句を省略することができます。 以下のように素直に単純な式の結果を計算させることができます。

    SELECT 2+2;

     ?column?
    ----------
            4

他のSQLデータベースでは、こういった`SELECT`を行うためにはダミーの1行テーブルを使わなければなりません。

明確さはありませんが、普通の`SELECT`からテーブルを省く、以下のような方法があります。

    SELECT distributors.* WHERE distributors.name = 'Westward';

     did |   name
    -----+----------
     108 | Westward

これは、`SELECT`で参照されるけれども `FROM`では記述されないテーブルが、暗黙の`FROM`アイテムに追加されるので、動作します。

これは便利な省略形ですが、間違って使いやすいです。 例えば、次のコマンド

    SELECT distributors.* FROM distributors d;

はおそらく間違いです。 ほとんどのユーザは、

    SELECT d.* FROM distributors d;

を意図し、実際に得られる制約の無い結合

    SELECT distributors.* FROM distributors d, distributors distributors;

を意図しないでしょう。 この種の間違いを検出できるように、PostgreSQLは、明示的な`FROM`句があっても、暗黙的な`FROM`機能が`SELECT`文で使用されている場合に警告を発します。 また、add_missing_fromパラメータを偽に設定することで、暗黙的な`FROM`機能を無効にすることができます。

### `AS` キーワード

標準SQLでは、省略可能な`AS`キーワードは単なるノイズで、その意味に影響すること無く省略することができます。 PostgreSQLのパーサは出力列の名前を変更する際にこのキーワードを必要とします。 なぜなら、型の拡張機能を考えると、このキーワードがないと構文解析の不明瞭さにつながるからです。 しかし、`FROM`アイテムでは`AS`は省略可能です。

### `GROUP BY`と`ORDER BY`における利用可能な名前空間

SQL-92では、`ORDER BY`句は、結果の列名か序数のみを使用することができ、`GROUP BY`句は、入力列名からなる式のみを使用できます。 PostgreSQLは、これらの句でそれぞれ他の選択が同じようにできるように拡張しています。 (しかし不明瞭さがある場合は標準の解釈が使用されます。) また、PostgreSQLではどちらの句にも任意の式を指定できます。 式で使われる名前は常に結果列の名前ではなく入力列の名前としてみなされることに注意してください。

SQL:1999では、SQL-92との上位互換性が全く無い、多少異なった定義を使用します。 しかし、ほとんどの場合、PostgreSQLはSQL:1999と同じ方法で`ORDER BY`や`GROUP BY`を解釈します。

### 非標準句

`DISTINCT ON`、`LIMIT`、`OFFSET`句は標準SQLでは定義されていません。

前のページ | ホーム | 次のページ
SAVEPOINT | 上に戻る | SELECT INTO