SELECT

Name

SELECT  --  テーブルもしくはビューから行を取り出す。

Synopsis

SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
    expression [ AS name ] [, ...]
    [ INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table ]
    [ FROM table [ alias ] [, ...] ]
    [ WHERE condition ]
    [ GROUP BY column [, ...] ]
    [ HAVING condition [, ...] ]
    [ { UNION [ ALL ] | INTERSECT | EXCEPT } select ]
    [ ORDER BY column [ ASC | DESC | USING operator ] [, ...] ]
    [ FOR UPDATE [ OF class_name [, ...] ] ]
    LIMIT { count | ALL } [ { OFFSET | , } start ]
  

入力

expression

テーブルの列名または式。

name

列または式の別名を AS 句を使用して指定します。 この名前は主に列のラベル表示用に使われます。 また、この名前は ORDER BY や GROUP BY 句内で列の値を 参照するためにも使われます。 しかし、name は WHERE や HAVING 句では使用できません。 この場合は式を略さずに記述して下さい。

TEMPORARY, TEMP

TEMPORARY もしくは TEMP が指定された場合、このセッショ ンで一意となるテーブルが作成され、セッション終了時に自 動的に削除されます。

new_table

INTO TABLE 句が指定された場合、問い合わせの結果は指定さ れた名前の別のテーブルに保存されます。 対象となる( new_table ) テーブルは、自動的に作成されますので、このコマンド実行前に 存在してはいけません。 より詳しくは SELECT INTO を参照して下 さい。

Note: CREATE TABLE AS 文もまた、select 問い合わせから新しいテーブルを作成します。

table

FROM 句で参照される、既存のテーブル名。

alias

直前の table の別名。 簡潔にするため、または、1 つのテーブル内での結合の際に 曖昧な部分を除去するために使用されます。

condition

その結果として true または false を返すブール式。 WHERE 句を参照して下さい。

column

テーブルの列名。

select

ORDER BY 及び LIMIT 句以外の全ての機能を持つ select 文。

出力

問い合わせで指定された結果の行の完全な集合。

count

問い合わせによって返される行数。

説明

SELECT は 1 つ以上のテーブルから行を返します。 選択の候補は、WHERE 条件を満たす行です。 WHERE が省略された場合は全ての行がその候補となります。 (WHERE 句 を参照し て下さい。)

DISTINCT は結果から重複する行を除きます。 (デフォルトの) ALL は重複分を含め、全ての 候補となる行を返します。

DISTINCT ON は指定された全ての式に合致す る行に対して、最初の行だけを残し、他の重複分を除去します。 "DISTINCT ON 式" は "ORDER BY 項目" と同じルールを使用して 解釈されます。 以下を参照して下さい。 各集合の "最初の行" は、ORDER BY が無い 限り予想できないことに注意して下さい。 ORDER BY を使用して、所望する行が確実に 最初に現れるようにします。例えば、

        SELECT DISTINCT ON (location) location, time, report
        FROM weatherReports
        ORDER BY location, time DESC;
   
は、各地区における最新の天気予報を取り出します。 もし、ORDER BY を使って各地区の時間の順序を降順にしていな かったとすると、それぞれの地区でのとんでもない日付の天気予報が 取り出されることになります。

GROUP BY 句を使って、1つのテーブルを複数の値に合致する行の グループに分割することができます。 (GROUP BY 句 を 参照して下さい。)

HAVING 句を使って、上記の行グループから条件に合致するもののみを 取り出すことができます。 (HAVING 句 を参照 して下さい)

ORDER BY 句によって、返される行を指定された順番でソートできます。 ORDER BY が無い場合、システムが最も低いコストで見つけた順番で、 行が返されます。 (ORDER BY 句 を 参照して下さい。)

UNION 演算子を使用して、実行した複数の問い合わせから返される行 をまとめたものを結果とすることができます。 (UNION 句 を参照 して下さい)

INTERSECT 演算子は 2 つの問い合わせの共通部分となる行を返します。 (INTERSECT 句 を参照して下さい。)

EXCEPT 演算子は、最初の問い合わせにあり、2 番目の問い合わせに ない行を返します。 (EXCEPT 句 を参照 して下さい。)

FOR UPDATE 句を使用して、この SELECT 文で選択された行を排他 的ロックすることができます。

LIMIT 句を使用して、問い合わせによって選択された行の一部分を ユーザに返すことができます。

テーブルから値を読みとるためには、そのテーブルに SELECT 権限 を持つ必要があります。

WHERE 句

オプションである、WHERE 句は一般的に以下の形式です。

WHERE boolean_expr
    
boolean_expr は、評価結果としてブール値をとる任意の式から構成されます。 多くの場合、この式は、
     expr cond_op expr
    
もしくは、
     log_op expr
    
となります。ここで、 cond_op は、 =、 <、<=、>、>= 、<>、または、ALL、ANY、 IN、LIKE などの条件演算子、ローカルに定義された演算子の内の いずれかです。 また、log_op は、AND, OR, NOT のいずれかです。 SELECT は WHERE 条件が TRUE を返さない行を全て無視します。

GROUP BY 句

GROUP BY はここで指定された句ごとにテーブルをグループ化します。

GROUP BY column [, ...]
    

GROUP BY はグループ化された列にて同一値を持つ全ての選択行を 1 つの行にまとめます。 集約関数がある場合、各グループを構成する全ての行に対して演算がな され、グループ毎にその値を生成します。 (これに対して、GROUP BY が無い場合の集約は、選択された行全てに 対して演算がなされ、1 つの値を生成します。) GROUP BY がある場合、集約関数の内側以外でグループ化されていない 列を参照するものを、SELECT の出力式に書くことができません。 グループ化されていない列を返す時に、1つ以上の値があり得るか らです。

GROUP BY 内の項目も、名前もしくは出力列の序数(SELECT 式)で指 定することも、入力列の値から形成された任意の式を指定すること もできます。 曖昧な場合、GROUP BY の名前は出力列名ではなく入力列名として 解釈されます。

HAVING 句

オプションである、HAVING 条件は一般的に以下の形式です。

HAVING cond_expr
    
ここで、cond_expr は WHERE 句で指定するものと同一です。

HAVING は 指定した cond_expr を満たさ ないグループの行を除去してグループ化されたテーブルを取り出します。 HAVING は WHERE と以下の点で異なります。 WHERE は GROUP BY を適用する前に個々の行を処理します。一方、 HAVING は GROUP BY によって生成されたグループ化された行を処理 します。

cond_expr 内で参 照される各列は、集約関数の内部に現れない限り、明瞭にあるグ ループ化された列を参照します。

ORDER BY 句

ORDER BY column [ ASC | DESC ] [, ...]
    

column には、結果 列名または序数を指定できます。

序数は結果列の位置を(左から右に数えた)順序で参照します。 この機構によって、適切な名前を持たない列を元に順番を定義 することができます。 これは絶対に必要なものではありません。 というのは、AS 句を下のように使えば、常に結果列に名前を割 り当てることができるからです。

SELECT title, date_prod + 1 AS newlen FROM films ORDER BY newlen;
    

ORDER BY に任意の式を指定することもできます。(SQL92への拡張です。) また、この式には SELECT 結果リストに現れないフィールドを持た せることもできます。 つまり、以下の文も正当なものです。

SELECT name FROM distributors ORDER BY code;
    
ORDER BY の項目が単純な名前であり、その名前が結果列名にも 入力列名にも合う場合、ORDER BY は結果列名として解釈す ることに注意して下さい。 これは、同じ条件における GROUP BY の選択とは反対です。 この不整合は、SQL92 標準で要求しているものです。

オプションとして、ORDER BY 句の各列名の後にキーワード DESC(逆方向) もしくは ASC(順方向) を付けることができます。 別の方法として、特殊な順序演算子名を指定することもできます。 ASC は '<' を使用した場合と、DESC は '>' を使用した場合 と同一です。

UNION 句

table_query UNION [ ALL ] table_query
    [ ORDER BY column [ ASC | DESC ] [, ...] ]
    
ここで、table_query には ORDER BY または LIMIT 句を持たない任意の select 式を指定 します。

UNION 演算子によって、呼び出された問い合わせから返される行をま とめたものを結果とすることができます。 UNION の引数として直接指定された 2 つの SELECT 文の出力は、同一 の列数でなければならず、また、対応する列のデータ型には 互換性がなければなりません。

デフォルトでは、ALL 句が指定されていない限り、UNION の結果には 重複行を含みません。

1 つの SELECT 文内の複数のUNION 演算子は、左から右に評価されます。 キーワード ALL は当然グローバルなものではなく、現在の 2 つのテー ブルの結果に対してのみ適用されます。

INTERSECT 句

table_query INTERSECT table_query
    [ ORDER BY column [ ASC | DESC ] [, ...] ]
    
ここで、 table_query には、ORDER BY または LIMIT 句を持たない任意の select 式を 指定します。

INTERSECT 演算子によって、2 つの問い合わせに共通する行を取り 出すことができます。 INTERSECT の引数として直接指定された 2 つの SELECT 文の出力は、 同一の列数でなければならず、また、対応する列のデータ型 には互換性がなければなりません。

1 つの SELECT 文内の複数の INTERSECT 演算子は、括弧による指示 が無い限り、左から右に評価されます。

EXCEPT 句

table_query EXCEPT table_query
     [ ORDER BY column [ ASC | DESC ] [, ...] ]
    
ここで、 table_query には、ORDER BY または LIMIT 句を持たない select 式を指定します。

EXCEPT 演算子によって、最初の問い合わせの結果にあり、次の問い 合わせの結果に無い行を取り出すことができます。 EXCEPT の引数として直接指定された 2 つの SELECT 文の出力は、 同一の列数でなければならず、また、対応する列のデータ型 には互換性がなければなりません。

1 つの SELECT 文内の複数の EXCEPT 演算子は、括弧による指示 が無い限り、左から右に評価されます。

LIMIT 句

    LIMIT { count | ALL } [ { OFFSET | , } start ]
    OFFSET start
    
ここで、 count には、返される行の最大数を指定します。また、 start には、行を返す前に何行飛ばすかを指定します。

LIMIT を使って、残りの問い合わせから生成された行の一部分のみを 取り出すことができます。 最大数の指定があれば、その数以上の行は返されません。 オフセットの指定があれば、行を返す前に指定数の行が飛ばされます。

LIMIT を使用する場合、ORDER BY 句を使って結果となる行が一意な順 序になるようにさせることを勧めます。 さもないと、問い合わせの行の内予期できない部分を得ることになりま す。 つまり、10 番目から12 番目までの行と指定することができるのですが、 どの様な順番における 10 番目から12 番目なのかということです。 ORDER BY の指定をしない限り、このどの様な順序かを判断することがで きません。

現在の Postgres 7.0 では、問い合わ せオプティマイザ は問い合わせ計画を生成する際に LIMIT を考慮 します。 このため、どのような LIMIT と OFFSET を指定したのかに依存して、 稀に異なった計画になる (行の順序の違いを引き起こす) ことがあり ます。 この結果、異なる LIMIT/OFFSET 値を使って、ある問い合わせの結果 から異なる部分を取り出す場合、ORDER BY を使用してその結果の順 序を予期できるようにしていない限り、その結果に不整合 が発生します。 これはバグではありません。 ORDER BY による順序の制約が付与されていなければ、SQL はある特定 の順番によって問い合わせの結果を生成することを確約していないとい う事実による、本来の結果です。

使用法

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
 Une Femme est une Femme   | 102 | Jean Luc Godard  | 1961-03-12 | Romantic
 Vertigo                   | 103 | Paramount        | 1958-11-14 | Action
 Becket                    | 103 | Paramount        | 1964-02-03 | Drama
 48 Hrs                    | 103 | Paramount        | 1982-10-22 | Action
 War and Peace             | 104 | Mosfilm          | 1967-02-12 | Drama
 West Side Story           | 105 | United Artists   | 1961-01-03 | Musical
 Bananas                   | 105 | United Artists   | 1971-07-13 | Comedy
 Yojimbo                   | 106 | Toho             | 1961-06-16 | Drama
 There's a Girl in my Soup | 107 | Columbia         | 1970-06-11 | Comedy
 Taxi Driver               | 107 | Columbia         | 1975-05-15 | Action
 Absence of Malice         | 107 | Columbia         | 1981-11-15 | Action
 Storia di una donna       | 108 | Westward         | 1970-08-15 | Romantic
 The King and I            | 109 | 20th Century Fox | 1956-08-11 | Musical
 Das Boot                  | 110 | Bavaria Atelier  | 1981-11-11 | Drama
 Bed Knobs and Broomsticks | 111 | Walt Disney      |            | Musical
(17 rows)

films から 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
(5 rows)

films から len 列の総和を求め、その結果 を kind でグループ化します。そして、総和が 5 時間未満となるグループを示します。

SELECT kind, SUM(len) AS total
    FROM films
    GROUP BY kind
    HAVING SUM(len) < INTERVAL '5 hour';

 kind     | total
----------+-------
 Comedy   | 02:58
 Romantic | 04:38
(2 rows)

以下の 2 つの例は、2 番目の列 (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
(13 rows)

次の例は distributors テーブルと actors テーブルから W という文字から始まるものの み抽出した結果からなる union をどのように取り出すのかを示したものです。

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

互換性

拡張

Postgres では問い合わせから FROM 句を省略することができます。 この機能は元々の PostQuel 問い合わせ言語から残っているも のです。

SELECT distributors.* WHERE name = 'Westwood';

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

SQL92

SELECT 句

SQL92 標準では、オプションキーワード "AS" はノイズでしかなく、その意味に影響すること無く省略できます。 Postgres のパーサは列名を変更 する場合にこのキーワードを必要とします。型拡張機能がこのコン テキストで曖昧な解析を引き起こしてしまうためです。

DISTINCT ON 句は SQL92 にはありません。 LIMIT と OFFSET も同様です。

SQL92 では、ORDER BY 句は結果列名また は序数のみを指定でき、GROUP BY 句では入力列名のみを指定 できます。 Postgres は、これらの句それぞれが 互いに同様な選択ができるように拡張しています。(しかし、あいま いな場合標準にしたがった解釈がなされます。) また、Postgres では、どちらの句で も任意の式を指定できます。 式に現れる名前は常に、結果列名ではなく、入力列名とみな されることに注意して下さい。

UNION 句

SQL92 における UNION の構文では、更に CORRESPONDING BY 句を使うことができます。

 
table_query UNION [ALL]
    [CORRESPONDING [BY (column [,...])]]
    table_query
     

CORRESPONDING BY 句は Postgres ではサポートされていません。