評価式は、たとえばSELECT コマンドのターゲットリストとして、INSERT や UPDATE の新しい列の値として、もしくはいくつかのコマンドの検索条件としてさまざまな文脈のなかで使われます。評価式の結果は、テーブル式の結果(つまりテーブル)から区別するために、スカラーと呼ばれることもあります。したがって、評価式はスカラー式(もしくはもっと簡単に式)とも呼ばれます。式の構文によって、算術、論理、集合などの演算を行う基本的な部分で値の計算を行うことができます。
評価式は下記のうちのどれかです。
定数あるいはリテラル値(Section 1.1.2を参照)。
列の参照。
関数宣言の本体における、位置パラメータ参照。
演算子の呼び出し
関数の呼び出し。
集約式
型キャスト
スカラー副問い合わせ
副式をグループ化したり優先順位を変更するのに便利な、括弧で囲まれた別の評価式。
これ以外にも、式として分類されるけれども一般的な構文ルールには従わないいくつかの構成要素があります。 これらは一般的に関数あるいは演算子の意味を持ちます。Chapter 6 で説明されていますが、例をあげると IS NULL があります。
Section 1.1.2ですでに定数については説明しました。続く節では残りのオプションについて説明します。
列は下記のような形式で参照することができます。
correlation.columnname
または
correlation.columnname[subscript]
(ここでは角括弧 [ ] は、文字通り表示するためのものです。)
correlation (相関名) は、テーブル名 (修飾されている場合もあり)、FROM 句で定義されたテーブルの別名、あるいは NEW または OLD というキーワードです。(NEW と OLD は書き換えルールでしか使用されませんが、他の相関名はすべての SQL 文で使用することができます。)相関名と区切り用のドットは、もし列名が現在の問い合わせで使われるすべてのテーブルを通して一意である場合は省略してもかまいません。 (Chapter 4 も参照してください。)
もしcolumnname が配列型の場合には、オプションの subscript(配列要素)で配列から特定の1つまたは複数の要素を選択します。もし配列要素が提供されない場合、配列全体が選択されます。(配列についての詳細はSection 5.12 を参照して下さい。
位置パラメータ参照は、外部から SQL 文に渡されるパラメータを示すために使用されます。 パラメータは SQL 関数定義および準備済み問い合わせの中で使用されます。 パラメータ参照の形式は以下のとおりです。
$number
たとえば、関数 dept の定義が以下のようにされたとします。
CREATE FUNCTION dept (text) RETURNS dept AS 'SELECT * FROM dept WHERE name = $1' LANGUAGE SQL;
ここでは $1 は関数が呼び出されるときに最初の関数引数によって置き換えられます。
演算子の呼び出しには以下の 3 構文が可能です。
expression operator expression(二項中置演算子) |
operator expression(単項前置演算子) |
expression operator(単項後置演算子) |
OPERATOR(schema.operatorname)
どんな特定の演算子が存在し、それが単項か二項かかどうかは、システムやユーザによってどんな演算子が定義されたかに依存します。Chapter 6 にて、組み込み済みの演算子について説明します。
関数呼び出しの構文は、関数名 (スキーマ名で修飾されている場合があります) に続けてその引数を括弧で囲んでリストしたものです。
function ([expression [, expression ... ]] )
たとえば、以下のものは 2 の平方根を計算します。
sqrt(2)
組み込み関数のリストはChapter 6にあります。他の関数はユーザによって追加できます。
集約式は、問い合わせによって選択される行に対して集約関数が適用されることを意味します。集約関数は、たとえば入力の合計や平均などのように、複数の入力を単一の出力値にします。集計式の構文は下記のうちのいずれかです。
aggregate_name (expression) aggregate_name (ALL expression) aggregate_name (DISTINCT expression) aggregate_name ( * )
ここで aggregate_name は前もって定義された集約で (修飾名の場合もあります)、expression 自体は集約式を含まない評価式です。
集約式の最初の形式は、指定された式が非 null 値を返す入力行すべてについての集計を呼び出します。 (実際には NULL 値を無視するかどうかは集約関数によって異なりますが、すべての標準的な集約関数では無視します。) ALL はデフォルトなので、2 つ目の形式は最初の形式と同じです。 3 番目の形式は、入力行の中にある式の、すべての別個の非 NULL 値の集計を呼び出します。 最後の形式は NULL 値か非 NULL 値かにかかわらず、それぞれの入力行に対して 1 回ずつ集計を呼び出します。特定の入力値が指定されていないため、これは一般的に count() 集約関数でのみ役に立ちます。
たとえば、count(*) は入力行の合計数を出します。 count(f1) は f1 が非 NULL である入力行の数を出します。 count(distinct f1) はf1 の別個の非 NULL 値の数を出します。
すでに定義された集約関数は Section 6.14で説明されています。他の集約関数はユーザによって追加することができます。
型キャストは、あるデータ型から他のデータ型への変換を指定します。PostgreSQL は型キャストに 2 つの等価な構文を受け付けます。
CAST ( expression AS type ) expression::type
CAST 構文は SQL に準拠したものです。:: とともに使用する構文は、PostgreSQL で伝統的に使用されている方法です。
キャストが既知の型の評価式に適用された場合、それは実行時型変換を表します。このキャストは、適切な型変換関数が使用可能であれば成功します。Section 1.1.2.4 で示すように、これと定数のキャストの使用との微妙な違いに注意して下さい。修飾されていない文字列リテラルに対するキャストは、リテラル定数値の初期に割り当てられる型を表します。 ですから、これは(文字列リテラル定数の内容がそのデータ型の入力構文で受け付けられるのであれば)全ての型で成功します。
通常 (たとえば、テーブル列への代入時など)、評価式が生成しなければならない型に曖昧さがない場合、明示的な型キャストは省略することができます。 その場合、システムは自動的に型キャストを適用します。 しかし、自動キャストは、システムカタログに "OK to apply implicitly" と示されている場合にのみ実行されます。 その他のキャストは明示的なキャスト構文で呼び出す必要があります。 この制限は、知らないうちに変換が実行されてしまうことを防ぐためのものです。
また、関数のような構文を使用して型キャストを指定することもできます。
typename ( expression )
しかし、これはその型の名前が関数の名前としても有効な場合にのみ動作します。 たとえば、double precision はこの方式で使用できませんが、同等の float8 は使用できます。また、interval、time、timestamp という名前は、構文が衝突するため、二重引用符で括った場合にのみこの方式で使用できます。このように、この関数のようなキャスト構文は一貫性がなくなりますので、おそらくは新しいアプリケーションでは使用すべきではありません。 (この関数のような構文は、実際には単なる関数呼び出しです。 2 つの標準的なキャスト構文のうちの 1 つが実行時変換で使用されると、この構文は登録済みの関数を内部的に呼び出して変換を実行します。 規則により、これらの変換関数は自身の出力型と同じ名前を持ちますが、これにより移植可能なアプリケーションで使用できるわけではありません。)
スカラー副問い合わせは、正確に 1 行 1 列を返す、括弧内の通常の SELECT 問い合わせです。 (問い合わせの書き方については Chapter 4 を参照してください。) その SELECT 問い合わせは実行され、返される 1 つの値はその値の前後の評価式で使用されます。 1 行を越える行や 1 列を越える列がスカラー副問い合わせの問い合わせとして使用された場合はエラーになります。 (しかし、特定の式では、副問い合わせが行を返さない場合でもエラーとはなりません。 そのスカラー結果は NULL として扱われます。)問い合わせは、その回りの問い合わせ内の値を参照することができます。 その値は副問い合わせの評価時には定数として扱われます。Section 6.15 も参照して下さい。
例えば、以下は各州で最も人口の多い都市を検索します。
SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name) FROM states;
副式の評価の順序は定義されていません。 特に演算子や関数の入力は、必ずしも左から右などの決まった順序で評価されるわけではありません。
さらに、その式の一部を評価しただけで式の結果を判断できる場合には、他の副式がまったく評価されないこともあります。 たとえば、
SELECT true OR somefunc();
では、(おそらく) somefunc() は呼び出されないでしょう。 以下の場合も同様です。
SELECT somefunc() OR true;
これは一部のプログラミング言語に見られる、ブーリアン演算子での左から右への"ショートサーキット"とは異なることに注意してください。
そのため、副次作用がある関数を複雑な式の一部として使用することは推奨されません。 特に、WHERE 句および HAVING 句で副次作用や評価順を信頼するのは危険です。これらの句は、実行計画を作成する過程で頻繁に再処理されるからです。 これらの句のブール式 (AND/OR/NOT の組み合わせ) は、ブール代数の規則で許されるあるゆる方式で再編成できます。
評価の順序を強制するために、CASE 構文 (Section 6.12 を参照) を使用できます。 たとえば、次の式は WHERE 句で 0 除算を避ける方法としては信頼性の低いものです。
SELECT ... WHERE x <> 0 AND y/x > 1.5;
しかし、次のようにすれば安全です。
SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;
このような方法で使用される CASE 構文は最適化を妨げるものなので、必要な場合にのみ使用してください。