テーブル式テーブル式はテーブルを計算するためのものです。BY句、HAVING句を付けることができます。単純なテーブル式は、単にディスク上のいわゆる基本テーブルと呼ばれるテーブルを参照するだけです。複雑な式では、様々な方法で基本テーブルを修正したり、結合させて使用することができます。BY句、およびHAVING句は、FROM句で派生したテーブル上に対して次々に変換を実行するパイプラインを指定します。これらの変換によって仮想テーブルが1つ生成されます。この仮想テーブルの行が選択リストに渡され、問い合わせの出力行が計算されます。FROM句FROM句は、カンマで分けられたテーブル参照リストで与えられる1つ以上のテーブルから、1つのテーブルを派生します。...]]テーブル参照は、テーブル名(スキーマで修飾することもできます)、あるいは、副問い合わせ、JOINによる結合、これらの複雑な組み合わせなどの派生テーブルとすることができます。FROM句に複数のテーブル参照がある場合、クロス結合されます(テーブルの行のデカルト積が形成されます。BY句、およびHAVING句での変換対象となる中間的な仮想テーブルになり、最終的にはテーブル式全体の結果となります。テーブル参照で、テーブルの継承階層の親テーブルの名前を指定すると、テーブル名の前にONLYキーワードがない場合は、テーブル参照はそのテーブルだけでなくその子テーブルに継承されたすべての行を生成します。この参照は名前を指定したテーブルに現れる列のみを生成し、子テーブルで追加された列は無視されます。テーブル名の前にONLYを記述する代わりに、テーブル名の後に*を記述して、子テーブルが含まれることを明示的に指定することができます。この動作は(sql_inheritance設定オプションの設定を変更していない限り)デフォルトですので、*を記述することは必要ありません。*を記述してさらにテーブルが検索されることを強調することができますので有用かもしれません。結合テーブル結合テーブルは、2つの(実または派生)テーブルから、指定した結合種類の規則に従って派生したテーブルです。クロス結合が使用可能です。]すべての結合は、互いに結び付けたり、あるいは入れ子にしたりすることができます。T1とT2のどちらか、あるいは両方が、結合テーブルになることがあります。括弧でJOIN句を括ることで結合の順序を制御することができます。括弧がない場合、JOIN句は左から右に入れ子にします。T2T1およびT2からのすべての可能な行の組み合わせ(つまりデカルト積)に対し、結合されたテーブルはT1のすべての列の後にT2のすべての列が続く行を含みます。同じです(下記を参照)。注記3つ以上のテーブルが現れた場合、この後者の等価性は厳密には保たれてはいません。JOINはカンマより強固に結合するためです。最初のケースではconditionがT1を参照できますが、2番目ではできないからです。T2INNERやOUTERは省略可能です。INNERがデフォルトとなります。LEFT、RIGHT、FULLは外部結合を意味します。結合条件は、ON句かUSING句で指定するか、またはNATURAL記述で暗黙的に指定します。結合条件は、以下で詳しく説明するように、2つの元となるテーブルのどの行が「一致するか」を決めます。限定的な結合には次のものがあります。JOIN(内部結合)T1の各行R1に対して、T2において行R1との結合条件を満たしている各行が、結合されたテーブルに含まれます。JOIN(左外部結合)まず、内部結合が行われます。その後、T2のどの行との結合条件も満たさないT1の各行については、T2の列をNULL値として結合行が追加されます。したがって、連結されたテーブルは常にT1の行それぞれに少なくとも1つの行があります。JOIN(右外部結合)まず、内部結合が行われます。その後、T1のどの行の結合条件も満たさないT2の各行については、T1の列をNULL値として結合行が追加されます。これは左結合の反対です。結果のテーブルは、T2の行が常に入ります。JOIN(完全外部結合)まず、内部結合が行われます。その後、T2のどの行の結合条件も満たさないT1の各行については、T2の列をNULL値として結合行が追加されます。T1のどの行でも結合条件を満たさないT2の各行に対して、T1の列をNULL値として結合行が追加されます。ON句は最も汎用的な結合条件であり、WHERE句で使われるものと同じ論理値評価式となります。ON式の評価が真となる場合、T1およびT2の対応する行が一致します。USING句は、結合の両側で結合列に同じ名前を使っているという特別な状況の利点を活かすことができる省略形です。それは、結合テーブルが共通で持つ列名をカンマで区切ったリストから、それぞれの列の等価性を結合条件として生成します。T2.bという結合条件を生成します。USINGの出力は、冗長列を抑制します。マッチした列は両方が同じ値を待つので両方を出力する必要がありません。すべての列を生成します。USINGは指定された列のペアのそれぞれについて1つの出力(結合リストでの指定順)、続いてT1の残りの列、その後にT2の残りの列を出力します。最後に、NATURALはUSINGの略記形式で、2つの入力テーブルの両方に含まれているすべての列名で構成されるUSINGリストを形成します。USINGと同様、これらの列は出力テーブルに一度だけ現れます。TRUEと同様に動作し、クロス積結合を生成します。注記USINGは、リストされている列のみ結合するのでリレーションの列の変更から適度に安全です。NATURALは、USINGよりもかなり危険です。いずれかのリレーションのスキーマ変更により新しくマッチする列名が作られると、結合にその新しい列も使われるようになってしまうからです。zzzを想定すると、以下のように様々な結合に関する結果が得られます。rows)ONで指定される結合条件には、結合に直接関係しない条件も含めることができます。これは一部の問い合わせにおいては便利ですが、使用の際には注意が必要です。rows)WHERE句の中に制約を記述すると異なる結果になることに注意してください。row)この理由はON句の中の制約は結合の前に処理され、一方WHERE句の中の制約は結合の後に処理されることによります。これは内部結合には影響がありませんが、外部結合には大きな影響があります。テーブルと列の別名テーブルや複雑なテーブル参照に一時的な名前を付与し、問い合わせの以降の部分では、その名前を使ってテーブルや複雑なテーブル参照を利用することができます。これをテーブルの別名と呼びます。テーブルの別名を作成するには以下のようにします。aliasASキーワードはなくても構わないノイズです。aliasは任意の識別子になります。テーブルの別名の一般的な適用法は、長いテーブル名に短縮した識別子を割り当てて結合句を読みやすくすることです。a.num;現在の問い合わせに関しては、別名がテーブル参照をする時の新しい名前になります。問い合わせの他の場所で元々の名前でテーブルを参照することはできなくなります。よって、次の例は有効ではありません。間違いテーブルの別名は主に表記を簡単にするためにあります。次のように、1つのテーブルが自分自身と結合する場合は、必須となります。副問い合わせを参照)の場合に別名が必要になります。括弧は曖昧さをなくすために使われます。次の例では、最初の文で2つ目のmy_tableのインスタンスにbという別名を付与し、一方、2つ目の文では結合結果に対して別名を付与しています。...次のような形式でテーブル別名を付けて、テーブル自身と同様にテーブルの列に一時的な名前を付けることができます。)もし、実際のテーブルが持つ列よりも少ない数の列の別名が与えられる場合、残りの列は改名されません。この構文は、自己結合あるいは副問い合わせで特に役立ちます。別名がJOIN句の結果に適用される場合、別名はJOIN内で参照される元々の名を隠します。cは有効ではありません。テーブルの別名aは、別名cの外側では参照することができません。副問い合わせ派生テーブルを指定する副問い合わせは括弧で囲む必要があります。テーブルと列の別名にあるように)必ずテーブル別名が割り当てられている必要があります。alias_nameと同じです。副問い合わせがグループ化や集約を含んでいる場合は、単純結合にまとめることはできない、より重要な例が発生します。副問い合わせをVALUESリストとすることもできます。last)繰り返しますが、テーブルの別名が必要です。VALUESリストの列に別名を付与することは省略することもできますが、付与することを勧めます。VALUESリストを参照してください。テーブル関数テーブル関数は、基本データ型(スカラ型)、もしくは複合データ型(テーブル行)からなる行の集合を生成する関数です。これらは、問い合わせのFROM句内でテーブル、ビュー、副問い合わせのように使用されます。テーブル関数から返される列は、テーブル、ビュー、副問い合わせの列と同様の手順で、SELECT、JOIN、WHEREの中に含めることができます。FROM構文を使用することで、それらの返却列を一緒に組み合わせることもできます。このときの結果の行数は、行数が最大となる関数の結果と同じになり、少ない結果側は多い結果に合わせてnull値で埋められます。ORDINALITY句が指定されている場合、関数の結果の列にbigint型の列が追加されます。この列は関数の結果の行を1から数えます。ORDINALITYの一般化です。デフォルトでは、この序数(ordinal)の列はordinalityになります。別の名前をAS句を使用して別名を割り当てることができます。特別なテーブル関数UNNESTは、任意の数の配列パラメータで呼ぶことができます。FROM構文を使用して結合されているかのようになります。])]]table_aliasが指定されない場合、テーブル名として関数名が使用されます。FROM()の場合は最初の関数名が使用されます。列に別名が提供されない場合、基本データ型を返す関数に対しては、列名も関数名と同じになります。複合型を返す関数の場合は、結果の列は型の個々の属性の名前を取得します。vw_getfoo;呼び出し方法に応じて異なる列集合を返すテーブル関数を定義することが役に立つ場合があります。これをサポートするために、テーブル関数をrecord擬似型を返すものと宣言することができます。した関数を問い合わせで使用する場合、システムがその問い合わせをどのように解析し計画を作成すればよいのかが判断できるように、想定した行構造を問い合わせ自身内に指定しなければなりません。この構文は次のようになります。FROM()構文を使用しない場合は、column_definitionのリストがFROM項目に取り付けることができる列の別名の代わりとなります。列の定義内の名前は、列の別名として機能します。FROM()構文を使用する場合は、column_definitionリストを個別に各メンバー関数に添付することができます。FROM()の後ろの列別名のリストの場所に書くことができます。'bytea%';dblink関数(dblinkモジュールの一部)は遠隔問い合わせを実行します。これは任意の問い合わせで使用できるように、recordを返すものと宣言されています。実際の列集合は、パーサが例えば*がどのように展開されるかを理解できるように、呼び出した問い合わせ内で指定されなければなりません。副問い合わせFROMに現れる副問い合わせの前にキーワードLATERALを置くことができます。すると、副問い合わせは先行するFROM項目によって提供される列を参照できます。(LATERALがない場合、それぞれの副問い合わせは個別に評価され、従ってその他のFROM項目を相互参照できません。)FROMに現れるテーブル関数の前にもキーワードLATERALを置くことが可能ですが、関数に対してこのキーワードは省略可能です。FROM項目により提供される列の参照を含むことができます。LATERAL項目はFROMリストの最上層、またはJOIN木の中で表示することができます。後者の場合、右側にあるJOINの左側のすべての項目を参照することが可能です。FROM項目がLATERAL相互参照を含む場合の評価は以下のようになります。相互参照される列(複数可)を提供するFROM項目のそれぞれの行、もしくは列を提供する複数のFROM項目の行一式に対し、LATERAL項目は列の行または複数行の一式の値により評価されます。結果行(複数可)は通常のように演算された行と結合されます。元となるテーブル(複数可)の列からそれぞれの行、または行の一式に対し反復されます。LATERALの些細な例としては以下があげられます。ss;上記は以下のより伝統的なやり方と全く同じ結果をもたらしますので特別に有用ではありません。foo.bar_id;LATERALは、結合される行を計算するために相互参照する列を必須とする場合、第一義的に有用です。一般的な利用方法は、集合を返す関数に対して引数の値を提供することです。vertices(polygon)が多角形の頂点の組みを返す関数だとして、以下のようにしてテーブルに格納されている多角形の互いに近接する頂点を特定できます。p2.id;この問い合わせは以下のようにも書くことができます。p2.id;そのほか幾つかの同等の定式化が考えられます。(既に言及したとおり、LATERALキーワードはこの例に於いて必要ではありませんが、明確に示すために使用しました。JOINの対象として、しばしば特に重宝します。LATERAL副問い合わせがそこから行を生成しない場合に於いても元となった行が結果に現れるからです。get_product_names()が製造者により生産された製品名を返すとして、テーブル内のいくつかの製造者が現在製品を製造していない場合、それらは何であるかを以下のようにして見つけることができます。WHERE句WHERE句の構文は以下の通りです。評価式を参照)も指定できます。FROM句の処理が終わった後、派生した仮想テーブルの各行は検索条件と照合されます。条件の結果が真の場合、その行は出力されます。ない(すなわち結果が偽またはNULLの)場合は、その行は捨てられます。一般的に検索条件は、FROM句で生成されたテーブルの最低1列を参照します。これは必須ではありませんが、そうしないとWHERE句はまったく意味がなくなります。内部結合の結合条件は、WHERE句でもJOIN句でも記述することができます。以下のテーブル式は等価です。5また、以下でも同じです。5どれを使うかは、主にスタイルの問題です。FROM句のJOIN構文はSQL標準であるにも関わらず、おそらく他のSQLデータベース管理システムへの移植性では劣るでしょう。外部結合については、FROM句以外に選択の余地はありません。外部結合のON句またはUSING句は、WHERE条件とは等しくありません。最終結果での行を除去すると同様に、(一致しない入力行に対する)行の追加となるからです。WHERE句の例を以下に示します。fdt.c1)fdtはFROM句で派生されたテーブルです。WHERE句の検索条件を満たさなかった行は、fdtから削除されます。評価式としてのスカラ副問い合わせの使い方に注目してください。他の問い合わせのように、副問い合わせは複雑なテーブル式を使うことができます。副問い合わせの中でどのようにfdtが参照されるかにも注意してください。c1をfdt.c1のように修飾することは、c1が副問い合わせの入力テーブルから派生した列名でもある時にだけ必要です。列名の修飾は、必須の場合ではなくても、明確にするために役立ちます。この例は、外側の問い合わせの列名の有効範囲を、どのようにして内側の問い合わせまで拡張するかを示します。BY句でグループ化し、また、HAVING句を使用して不要なグループを取り除くことができます。BY句で列挙されたすべての列で同じ値を所有する行をまとめてグループ化するために使用されます。列の列挙順は関係ありません。これは共通する値を持つそれぞれの行の集合をグループ内のすべての行を代表する1つのグループ行にまとめるものです。これは、出力の冗長度を排除したり、それぞれのグループに適用される集約計算を行うためのものです。xと書くことはできません。各グループに関連付けられる列yの単一の値がないからです。BYで指定した列はグループごとに単一の値を持つので、選択リストで参照することができます。BYでリストされていない列は集約式を除いて参照することはできません。集約式の例は以下の通りです。グループ全体について単一の値を計算する集約関数です。集約関数を参照してください。ヒント集約式を使用しないグループ化は、列内の重複しない値の集合を効率良く計算します。DISTINCTを参照)の使用で同じように達成することができます。(全製品の総売上ではありません)。BY句で指定する必要があります。これらは問い合わせ選択リストの中で使われているからです(ただし、以下を参照)。BYで指定する必要はありません。これは、製品ごとの売上計算の集約式(sum(...))の中だけで使われるためです。この問い合わせは、各製品に対して製品の全販売に関する合計行が返されます。productsテーブルが、例えば、product_idが主キーであるように設定されている場合、nameとprice列は製品ID(product_id)に関数依存しており、このため製品IDグループそれぞれに対してどのnameとpriceの値を返すかに関するあいまいさがありませんので、上の例ではproduct_idでグループ化することで十分です。BYは、元となるテーブルの列によってのみグループ化できますが、PostgreSQLでは、選択リストの列によるグループ化もできるように拡張されています。単純な列名の代わりに、評価式でグループ化することもできます。BYを使ってグループ化されたテーブルで特定のグループのみ必要な場合、結果から不要なグループを除くのに、WHERE句のようにHAVING句を使うことができます。構文は以下の通りです。boolean_expressionHAVING句内の式は、グループ化された式とグループ化されてない式(この場合は集約関数が必要になります)の両方を参照することができます。rows)次に、より現実的な例を示します。5000;上の例で、WHERE句は、グループ化されていない列によって行を選択している(この式では最近の4週間の売上のみが真になります)のに対し、HAVING句は出力を売上高が5000を超えるグループに制限しています。集約式が、問い合わせ内で常に同じである必要がないことに注意してください。BY句がない場合でも、グループ化は依然として行われます。結果は単一グループ行(またはHAVINGで単一行が削除されれば、行が全くなくなるかもしれません)となります。BY句がまったく存在しなくても同じことが言えます。SETS、CUBE、ROLLUP上述のものよりも複雑なグループ化の操作は、グループ化セットの概念を用いることで可能です。BY句と同じように集約計算され、その後結果が返されます。SETSの各サブリストはゼロ個以上の列または式を指定することが出来ます。BY句で指定したのと同じように解釈されます。空のグループ化セットは、全行が一つのグループにまで集約されることを意味します(何も入力行が存在しない場合でも出力されます)。BY句がない集約関数の場合と同様です。グループ化している列または式の参照は、その列が現われないグループ化セットの結果行ではNULL値に置き換えられます。特定の出力行が、どのグループ化から生じたかを識別するには表9.55「グループ化演算」を参照して下さい。グループ化セットの中で一般的な2種類については、略記法での指定方法が提供されています。)上の句は、式の指定されたリストと空のリストを含めたリストのすべてのプレフィックスを表します。したがって、以下と同等です。))これは一般に、階層データに対する分析のために使用されます。よる総給与を出します。)上の句は、与えられたリストとその可能な部分集合(サブセット)のすべて(すなわち、べき集合)を表します。))CUBE句やROLLUP句の各要素は、個々の式、または括弧で囲まれた要素のサブリスト、どちらかに出来ます。後者の場合には、サブリストは個々のグループ化セットを生成する目的において一つの単位として扱われます。