<!--
$Header: /usr/prj/pg/cvsroot/doc/doc/src/sgml/query.sgml,v 1.13 2001/09/13 06:00:50 junichi Exp $
-->

 <chapter id="query">
<!--  <title>The Query Language</title> -->
  <title>問い合わせ言語</title>
<indexterm><primary sortas="といあわせげんご">問い合わせ言語</primary></indexterm>

<!--  <para>
   The  <productname>Postgres</productname>  query language is a variant of
   the <acronym>SQL</acronym> standard. It
   has many extensions to <acronym>SQL</acronym> such as an
   extensible type  system,
   inheritance,  functions and production rules. These are
   features carried over from the original
   <productname>Postgres</productname>  query
   language,  <productname>PostQuel</productname>.
   This section provides an overview
   of how to use <productname>Postgres</productname>
   <acronym>SQL</acronym>  to  perform  simple  operations.
   This manual is only intended to give you an idea of our
   flavor of <acronym>SQL</acronym> and is in no way a complete  tutorial  on
   <acronym>SQL</acronym>.  Numerous  books  have  been  written  on
   <acronym>SQL92</acronym>, including
   <xref linkend="MELT93" endterm="MELT93"> and
   <xref linkend="DATE97" endterm="DATE97">.
   You should be  aware  that  some language features 
   are extensions to the standard.
  </para> -->

  <para>
   <productname>Postgres</productname>の問い合わせ言語は<acronym>SQL</acronym>標準とは異なり、<acronym>SQL</acronym>に拡張可能な型システム、継承、関数、生成規則など多くの拡張がされたものになっています。これらは、オリジナルの<productname>Postgres</productname>の問い合わせ言語である<productname>PostQuel</productname>から引き継がれた機能です。この節ではごく簡単な操作を実行することで<productname>Postgres</productname> <acronym>SQL</acronym>の利用方法の概要を説明します。このマニュアルでは我々の<acronym>SQL</acronym>のフレーバーにおける考え方を示すものであり、<acronym>SQL</acronym>の完全なチュートリアルではありません。<xref linkend="MELT93" endterm="MELT93">や<xref linkend="DATE97" endterm="DATE97">など、<acronym>SQL92</acronym>について書かれている書籍はたくさんあります。いくつかの言語機能は標準に対する拡張であることを理解しておいてください。
  </para>

  <sect1 id="query-psql">
<!--   <title>Interactive Monitor</title> -->
   <title>インタラクティブモニタ</title>
<indexterm><primary sortas="いんたらくてぃぶもにた">インタラクティブモニタ</primary></indexterm>
<indexterm><primary>psql</primary></indexterm>

   <para>
<!--    In the examples that follow, we assume  that  you  have
    created  the mydb database as described in the previous
    subsection and have started <application>psql</application>.
    Examples  in  this  manual  can  also   be   found   in source distribution
    in the directory <filename>src/tutorial/</filename>.    Refer   to   the
    <filename>README</filename> file in that directory for how to use them.   To
    start the tutorial, do the following: -->

    この後の例では、前の章で説明したように、mydbデータベースを作成した上で<application>psql</application>を開始しているものとします。このマニュアルの例はソースコードディレクトリの<filename>src/tutorial/</filename>にあります。チュートリアルを開始する前に、以下を行ってください。</para>

<screen>
<prompt>$</prompt> <userinput>cd <replaceable>...</replaceable>/src/tutorial</userinput>
<prompt>$</prompt> <userinput>psql -s mydb</userinput>
<!-- <computeroutput>
Welcome to the POSTGRESQL interactive sql monitor:
  Please read the file COPYRIGHT for copyright terms of POSTGRESQL

   type &bsol;? for help on slash commands
   type &bsol;q to quit
   type &bsol;g or terminate with semicolon to execute query
   You are currently connected to the database: postgres
</computeroutput> -->
<computeroutput>
Welcome to psql, the PostgreSQL interactive terminal.

Type:  &bsol;copyright for distribution terms
       &bsol;h for help with SQL commands
       &bsol;? for help on internal slash commands
       &bsol;g or terminate with semicolon to execute query
       &bsol;q to quit
<!-- You are currently connected to the database: postgres -->
postgresユーザーとしてデータベースに接続しています。
</computeroutput>

<prompt>mydb=&gt;</prompt> <userinput>&bsol;i basics.sql</userinput>
</screen>

<!--   <para>
    The  <literal>&bsol;i</literal>  command  read  in  queries  from the specified
    files. The <literal>-s</literal> option puts you in single step mode which
    pauses  before  sending a query to the backend. Queries
    in this section are in the file <filename>basics.sql</filename>.
   </para> -->

   <para>
    <literal>&bsol;i</literal>コマンドは特定のファイルから問い合わせを読み込みます。<literal>-s</literal>オプションはバックエンドに問い合わせを送る前に一時休止するシングルステップモードです。このセクションで使用している問い合わせは<filename>basics.sql</filename>ファイルです。
   </para>

<!--   <para>
    <application>psql</application>
    has a variety of <literal>&bsol;d</literal> commands for showing system information.
    Consult these commands for more details;
    for a listing, type <literal>&bsol;?</literal> at the <application>psql</application> prompt.
   </para> -->

   <para>
    <application>psql</application>にはシステム情報を表示するさまざまな<literal>&bsol;d</literal>コマンドがあります。<application>psql</application>のプロンプトで<literal>&bsol;?</literal>と入力して詳細を参照してください。
   </para>
  </sect1>

  <sect1 id="query-concepts">
<!--   <title>Concepts</title> -->
   <title>概念</title>

<!--   <para>
    The fundamental notion in <productname>Postgres</productname> is
    that of a <firstterm>table</firstterm>, which is a named
    collection of <firstterm>rows</firstterm>.  Each row has the same
    set of named <firstterm>columns</firstterm>, and each column is of
    a specific type.  Furthermore, each row has a permanent
    <firstterm>object identifier</firstterm> (<acronym>OID</acronym>)
    that is unique throughout the database cluster.  Historially,
    tables have been called classes in
    <productname>Postgres</productname>, rows are object instances,
    and columns are attributes.  This makes sense if you consider the
    object-relational aspects of the database system, but in this
    manual we will use the customary <acronym>SQL</acronym>
    terminology.  As previously discussed,
    tables are grouped into databases, and a collection of databases
    managed by a single <application>postmaster</application> process
    constitutes a database cluster.
   </para> -->

   <para>
    <productname>Postgres</productname>における基本的概念は<firstterm>テーブル</firstterm>です。これは、<firstterm>行</firstterm>の集合に名前を付けたものです。各行には名前を付けられた<firstterm>カラム</firstterm>の同じセットがあり、各カラムは特定のデータ型です。さらに、各行はデータベースクラスタを通じて一意な<firstterm>object identifier</firstterm>（<acronym>OID</acronym>）が割り当てられています。歴史的に<productname>Postgres</productname>ではテーブルをクラス、行をオブジェクトインスタンス、カラムを属性と呼んでいます。これはデータベースシステムのオブジェクトリレーショナル的側面を考える場合には意味がありますが、このマニュアルでは慣習的な<acronym>SQL</acronym>用語を使用します。データベースはテーブルの集合であり、データベースの集合から構成されるデータベースクラスタは1つの<application>postmaster</application>プロセスに管理されます。
   </para>
  </sect1>

  <sect1 id="query-table">
<!--   <title>Creating a New Table</title> -->
   <title>新しいテーブルの作成</title>
<indexterm><primary sortas="てーぶる">テーブル</primary><secondary sortas="さくせい">作成</secondary></indexterm>
   <para>
<!--    You  can  create  a  new  table by specifying the table
    name, along with all column names and their types: -->

    テーブルはテーブル名とすべてのカラム名とそのデータ型を指定することによって作成することができます。</para>

<programlisting>
<!-- CREATE TABLE weather (
    city            varchar(80),
    temp_lo         int,           &bsol;-&bsol;- low temperature
    temp_hi         int,           &bsol;-&bsol;- high temperature
    prcp            real,          &bsol;-&bsol;- precipitation
    date            date
);  -->

CREATE TABLE weather (
    city            varchar(80),
    temp_lo         int,           -- 最低気温
    temp_hi         int,           -- 最高気温
    prcp            real,          -- 降水量
    date            date
);
</programlisting>

<!--   <para>
    Note that both keywords and identifiers are case-insensitive;
    identifiers can preserve case by surrounding them with
    double-quotes as allowed
    by <acronym>SQL92</acronym>.
    <productname>Postgres</productname>  <acronym>SQL</acronym>
    supports the usual
    <acronym>SQL</acronym> types <type>int</type>,
    <type>float</type>,  <type>real</type>,  <type>smallint</type>,
<type>char(N)</type>,  
    <type>varchar(N)</type>,  <type>date</type>, <type>time</type>,
    and <type>timestamp</type>, as well as other types of general utility and
    a rich set of geometric types.  As we will 
    see later, <productname>Postgres</productname> can be customized
    with an  
    arbitrary  number  of
    user-defined  data types.  Consequently, type names are
    not syntactical keywords, except where required to support special
    cases in the <acronym>SQL92</acronym> standard.
    So far, the <productname>Postgres</productname>
    <command>CREATE</command> command
    looks exactly  like
    the  command  used  to  create a table in a traditional
    relational system.  However, we will presently see that
    tables  have  properties  that  are  extensions of the
    relational model.
   </para> -->

   <para>
    キーワード群と識別子が大文字と小文字を区別しない点に注意してください。<acronym>SQL92</acronym>では識別子を二重引用符（""）で囲むことによってそのまま扱うことができます。<productname>Postgres</productname> <acronym>SQL</acronym>では<type>int</type>、<type>float</type>、<type>real</type>、<type>smallint</type>、<type>char(N)</type>、<type>varchar(N)</type>、<type>date</type>、<type>time</type>、<type>timestamp</type>などや他の一般的なユーティリティや豊富な幾何学データ型をサポートしています。後で紹介しますが、<productname>Postgres</productname>では任意の多くのユーザー定義データ型でカスタマイズすることも可能です。データ型の名称は<acronym>SQL92</acronym>の標準でサポートされる特別なケースを除いては文法的なキーワードではないものとなります。これまでは、<productname>Postgres</productname>の<command>CREATE</command>コマンドは、伝統的なリレーショナルシステムにおけるテーブルを作成するコマンドとまったく同じに見えたことでしょう。しかしながら、リレーショナルモデルを拡張した性質をもつテーブルなども見ることができるでしょう。
   </para>

  </sect1>

  <sect1 id="query-populate">
<!--   <title>Populating a Table with Rows</title> -->
   <title>一般的なテーブル</title>
<indexterm><primary sortas="てーぶる">テーブル</primary></indexterm>
   <para>
<!--    The <command>INSERT</command> statement is used to populate a table  with
    rows: -->

    <command>INSERT</command>文は、テーブルに行を登録（挿入）するのに使われます。</para>

<programlisting>
INSERT INTO weather VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');
</programlisting>

   <para>
<!--    You can also use <command>COPY</command> to load large
    amounts of data from flat (<acronym>ASCII</acronym>) files.
    This is usually faster because the data is read (or written) as a
    single atomic
    transaction directly to or from the target table. An example would be: -->

    <acronym>ASCII</acronym>のフラットファイルから大量のデータ登録を行うこともできます。これには<command>COPY</command>を使用します。これはターゲットのテーブルから、あるいはターゲットのテーブルへ直接1つのトランザクションとして読み込み（書き込み）されるので通常よりも高速です。例を示します。</para>
    
<programlisting>
COPY weather FROM '/home/user/weather.txt' USING DELIMITERS '|';
</programlisting>

<!--    where the path name for the source file must be available to the
    backend server
    machine, not the client, since the backend server reads the file directly. -->

<para>ソースファイルのパス名はクライアントがではなく、バックエンドサーバーマシンが直接ファイルを読めるところでなくてはいけません。

   </para>
  </sect1>

  <sect1 id="query-query">
<!--   <title>Querying a Table</title> -->
   <title>テーブルへの問い合わせ</title>
<indexterm><primary sortas="てーぶる">テーブル</primary><secondary sortas="といあわせ">問い合わせ</secondary></indexterm>
<indexterm><primary sortas="といあわせ">問い合わせ</primary></indexterm>
<indexterm><primary>SELECT</primary></indexterm>
   <para>
<!--
    The <classname>weather</classname> table can be queried with normal relational
    selection  and projection queries.  A <acronym>SQL</acronym>
    <command>SELECT</command> 
    statement is used to do this.  The statement is divided into
    a target list (the part that lists the columns to be
    returned) and a qualification (the part that  specifies
    any  restrictions).   For  example, to retrieve all the
    rows of weather, type:
-->

    <classname>weather</classname>テーブルは通常の選択と射影で問い合わせることができます。<acronym>SQL</acronym>の<command>SELECT</command>文がこの問い合わせに使用されます。文はターゲットリスト（復帰される列のリスト部分）と修飾子（制約を指定する部分）に分けられます。たとえば、weatherのすべての行を検索してみます。</para>

<programlisting>
SELECT * FROM weather;
</programlisting>

<!--    and the output should be: -->
<para>以下のように出力されます。</para>

<programlisting>
+--------------+---------+---------+------+------------+
|city          | temp_lo | temp_hi | prcp | date       |
+--------------+---------+---------+------+------------+
|San Francisco | 46      | 50      | 0.25 | 1994-11-27 |
+--------------+---------+---------+------+------------+
|San Francisco | 43      | 57      | 0    | 1994-11-29 |
+--------------+---------+---------+------+------------+
|Hayward       | 37      | 54      |      | 1994-11-29 |
+--------------+---------+---------+------+------------+
</programlisting>
<!--    You may specify any arbitrary expressions in the  target list. For 
    example, you can do: -->

<para>ターゲットリスト部分において任意の式を指定することができます。たとえば、以下のようにすることができます。</para>

<programlisting>
SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;
</programlisting>

   <para>
<!--    Arbitrary  Boolean  operators
    (<command>AND</command>,  <command>OR</command> and 
    <command>NOT</command>) are
    allowed in the qualification of any query.   For  example, -->

    任意のブーリアン演算子（AND、OR、NOT）はどんな問い合わせの修飾においても使用することができます。たとえば、以下のようにしてみましょう。</para>

<programlisting>
SELECT * FROM weather
    WHERE city = 'San Francisco'
    AND prcp > 0.0;
</programlisting>

<!-- results in: -->
<para>結果は以下のようになります。</para>

<programlisting>
+--------------+---------+---------+------+------------+
|city          | temp_lo | temp_hi | prcp | date       |
+--------------+---------+---------+------+------------+
|San Francisco | 46      | 50      | 0.25 | 1994-11-27 |
+--------------+---------+---------+------+------------+
</programlisting>

   <para>
<!--    As  a final note, you can specify that the results of a
    select can be returned in a <firstterm>sorted order</firstterm>
    or with duplicate rows removed. -->

    SELECTでは、<firstterm>並べ替え</firstterm>を行ったり、重複する行を削除した値を返すことができます。</para>

<programlisting>
SELECT DISTINCT city
    FROM weather
    ORDER BY city;
</programlisting>
  </sect1>

  <sect1 id="query-selectinto">
<!--   <title>Redirecting SELECT Queries</title> -->
   <title>SELECT問い合わせのリダイレクト</title>
<indexterm><primary sortas="といあわせ">問い合わせ</primary><secondary sortas="りだいれくと">リダイレクト</secondary></indexterm>
<indexterm><primary>SELECT INTO</primary></indexterm>
   <para>
<!--    Any <command>SELECT</command> query can be redirected to a new table -->
    
        <command>SELECT</command>の問い合わせ結果は新規テーブルにリダイレクトできます。</para>

<programlisting>
SELECT * INTO TABLE temp FROM weather;
</programlisting>

<!--   <para>
    This forms an implicit <command>CREATE</command> command, creating a new
    table temp with the column names and types specified
    in  the target list of the <command>SELECT INTO</command> command.  We can
    then, of course, perform any operations on the  resulting 
    table that we can perform on other tables.
   </para> -->

   <para>この場合、暗黙のうちに<command>CREATE</command>コマンドが実行されます。<command>SELECT INTO</command>コマンドのターゲットリストで指定されたカラム名とデータ型から新しく一時的なテーブルを作成します。もちろん作成されたテーブルは、他のテーブルと同じように操作することができます。</para>

  </sect1>

  <sect1 id="query-join">
<!--   <title>Joins Between Tables</title> -->
   <title>テーブルの結合</title>
<indexterm><primary sortas="てーぶる">テーブル</primary><secondary sortas="けつごう">結合</secondary></indexterm>
<!--   <para>
    Thus far, our queries have only accessed one table at a
    time.  Queries can access multiple tables at once,  or
    access  the  same  table  in  such  a way that multiple
    rows of the table are being processed at the  same
    time.   A query that accesses multiple rows of the
    same or different tables at one time is called a  join
    query.
    As an example, say we wish to find all the records that
    are in the  temperature  range  of  other  records.  In
    effect,  we  need  to  compare  the temp_lo and temp_hi
    columns of each WEATHER  row  to  the  temp_lo  and
    temp_hi  columns of all other WEATHER columns. -->

    <para>
    ここまで、問い合わせは1回に1つのテーブルのみにアクセスするだけでした。しかし、問い合わせは一度に複数のテーブルにアクセスすることができますし、またテーブルの複数行が同時に処理されている場合には同じテーブルにアクセスすることもできます。1回に同じもしくは異なるテーブルの複数行にアクセスする問い合わせは結合問い合わせと呼ばれます。例として、他のレコードの温度範囲にあるすべてのレコードを探したいとします。実際にはすべてのweatherテーブルの行のtemp_loとtemp_hiカラムにともう1つのweatherテーブルの行のtemp_loとtemp_hiカラムを比較する必要があります。</para>

    <note>
<!--     <para>
      This  is only a conceptual model.  The actual join may
      be performed in a more efficient manner, but this is invisible
      to the user.
     </para> -->

     <para>
     これは概念モデルだけです。実際の結合はより効率的な方法で実行されるかもしれませんが、ユーザーには見えません。
     </para>

    </note>

<!--    We can do this with the following query: -->

<para>以下の問い合わせでこれを実行することができます。</para>

<programlisting>
SELECT W1.city, W1.temp_lo AS low, W1.temp_hi AS high,
    W2.city, W2.temp_lo AS low, W2.temp_hi AS high
    FROM weather W1, weather W2
    WHERE W1.temp_lo < W2.temp_lo
    AND W1.temp_hi > W2.temp_hi;

+--------------+-----+------+---------------+-----+------+
|city          | low | high | city          | low | high |
+--------------+-----+------+---------------+-----+------+
|San Francisco | 43  | 57   | San Francisco | 46  | 50   |
+--------------+-----+------+---------------+-----+------+
|San Francisco | 37  | 54   | San Francisco | 46  | 50   |
+--------------+-----+------+---------------+-----+------+
</programlisting>     

    <note>
<!--     <para>
      The semantics of such a join are 
      that the qualification
      is a truth expression defined for the Cartesian  product  of
      the tables indicated in the query.  For those rows in
      the Cartesian product for which the qualification  is  true,
      <productname>Postgres</productname>  computes  and  returns the
      values specified in the target list.  
      <productname>Postgres</productname> <acronym>SQL</acronym>
      does not assign  any  meaning  to
      duplicate values in such expressions. 
      This means that <productname>Postgres</productname> 
      sometimes recomputes the same target list several times;
      this frequently happens when Boolean expressions are connected 
      with an "or".  To remove such duplicates, you must  use
      the <command>SELECT DISTINCT</command> statement.
     </para> -->
     <para>
      このような結合の意味論は、条件は問い合わせで指示したテーブルの直積のために定義された式であるということです。条件が真である直積にに含まれる行に対して、Postgresはターゲットリストで指定される値を計算して返します。<productname>Postgres</productname> <acronym>SQL</acronym>では、このような式において値が重複することはありません。これは<productname>Postgres</productname>がときどき同じターゲットリストに数回のを再計算を行うからです。ブーリアン演算子が「or」と組み合わされるときしばしばこれが起こります。重複を取り除くには<command>SELECT DISTINCT</command>文を使用しなければいけません。
     </para>
    </note>

<!--   <para>
    In this case, both <literal>W1</literal> and
    <literal>W2</literal>  are  surrogates for  a
    row of the table weather, and both range over all
    rows of the table.  (In the  terminology  of  most
    database  systems, <literal>W1</literal> and <literal>W2</literal> 
    are known as <firstterm>range variables</firstterm>.)  
    A query can contain an  arbitrary  number  of
    table names and surrogates.
   </para> -->

   <para>
    この場合、<literal>W1</literal>と<literal>W2</literal>のテーブルはweatherテーブルの行とテーブルのすべての行を越えた両方の範囲の代わりになるものです（大部分のデータベースシステムの用語においては、<literal>W1</literal>と<literal>W2</literal>は<firstterm>範囲変数</firstterm><indexterm><primary sortas="はんいへんすう">範囲変数</primary></indexterm>として知られています）。問い合わせは、任意の多くのテーブル名と代理名を記述することができます。
   </para>
  </sect1>

  <sect1 id="query-update">
<!--   <title>Updates</title> -->
   <title>更新</title>
<indexterm><primary sortas="でーた">データ</primary><secondary sortas="へんこう">変更</secondary></indexterm>
<indexterm><primary>UPDATE</primary></indexterm>

   <para>
<!--    You can update existing rows using the
    <command>UPDATE</command> command. 
    Suppose you discover the temperature readings are
    all  off  by 2 degrees as of Nov 28, you may update the
    data as follow: -->

    <command>UPDATE</command>コマンドを使用することにより、行を更新することができます。11月28日以降のすべての日の最高気温と最低気温を2度ずつ下げるとしたら、データを以下のように更新します。</para>

<programlisting>
UPDATE weather
    SET temp_hi = temp_hi - 2,  temp_lo = temp_lo - 2
    WHERE date > '1994-11-28';
</programlisting>
  </sect1>

  <sect1 id="query-delete">
<!--   <title>Deletions</title> -->
   <title>削除</title>
<indexterm><primary sortas="でーた">データ</primary><secondary sortas="さくじょ">削除</secondary></indexterm>
<indexterm><primary>DELETE</primary></indexterm>
   <para>
<!--    Deletions are performed using the <command>DELETE</command> command: -->
    削除は<command>DELETE</command>コマンドを使用して実行されます。</para>

<programlisting>
DELETE FROM weather WHERE city = 'Hayward';
</programlisting>

<!--    All weather recording belonging to Hayward are removed.
    One should be wary of queries of the form -->

<para>以下ではweatherテーブルからHaywardに関するすべての記録を削除します。この形式の問い合わせには十分に注意してください。</para>

<programlisting>
DELETE FROM <replaceable>tablename</replaceable>;
</programlisting>

<!--    Without a qualification, <command>DELETE</command> will simply
    remove  all  rows from the given table, leaving it
    empty.  The system will not request confirmation before
    doing this. -->

<para>条件が指定されていない場合、<command>DELETE</command>は指定されたテーブルのすべての行を削除してしまい、テーブルは空になってしまいます。実際に削除する前にシステムが実行を確認してくれたりはしません。
   </para>
  </sect1>

  <sect1 id="query-agg">
<!--   <title>Using Aggregate Functions</title> -->
   <title>集約関数の利用</title>
<indexterm><primary sortas="しゅうやくかんすう">集約関数</primary></indexterm>
<!--   <para>
    Like  most  other relational database products, 
    <productname>PostgreSQL</productname> supports
    aggregate functions.
    An aggregate function computes a single result from multiple input rows.
    For example, there are aggregates to compute the
    <function>count</function>, <function>sum</function>,
    <function>avg</function> (average), <function>max</function> (maximum) and
    <function>min</function> (minimum) over a set of rows.
   </para> -->

   <para>
    その他のリレーショナルデータベース製品のように、<productname>PostgreSQL</productname>も集約関数をサポートしています。集約関数は複数の入力行から単一の結果を計算するものです。たとえば、<function>count</function>、<function>sum</function>、<function>avg</function>（average）、<function>max</function>（maximum）、<function>min</function>（minimum）といった関数が一連の行を計算して集計を行います。<indexterm><primary>COUNT</primary></indexterm><indexterm><primary>SUM</primary></indexterm><indexterm><primary>AVG</primary></indexterm><indexterm><primary>MAX</primary></indexterm><indexterm><primary>MIN</primary></indexterm><indexterm><primary sortas="しゅうやくかんすう">集約関数</primary><secondary>COUNT</secondary></indexterm><indexterm><primary sortas="しゅうやくかんすう">集約関数</primary><secondary>SUM</secondary></indexterm><indexterm><primary sortas="しゅうやくかんすう">集約関数</primary><secondary>AVG</secondary></indexterm><indexterm><primary sortas="しゅうやくかんすう">集約関数</primary><secondary>MAX</secondary></indexterm><indexterm><primary sortas="しゅうやくかんすう">集約関数</primary><secondary>MIN</secondary></indexterm>
   </para>

<!--   <para>
    It is important to understand the interaction between aggregates and
    SQL's <command>WHERE</command> and <command>HAVING</command> clauses.
    The fundamental difference between <command>WHERE</command> and
    <command>HAVING</command> is this: <command>WHERE</command> selects
    input rows before groups and aggregates are computed (thus, it controls
    which rows go into the aggregate computation), whereas
    <command>HAVING</command> selects group rows after groups and
    aggregates are computed.  Thus, the
    <command>WHERE</command> clause may not contain aggregate functions;
    it makes no sense to try to use an aggregate to determine which rows
    will be inputs to the aggregates.  On the other hand,
    <command>HAVING</command> clauses always contain aggregate functions.
    (Strictly speaking, you are allowed to write a <command>HAVING</command>
    clause that doesn't use aggregates, but it's wasteful; the same condition
    could be used more efficiently at the <command>WHERE</command> stage.)
   </para> -->

  <para>
    集約とSQLの<command>WHERE</command>と<command>HAVING</command>節の間の相互作用を認識することは重要です。<command>WHERE</command>と<command>HAVING</command>の基本的な違いは以下のとおりです。<command>WHERE</command>はグループ化と集約計算する前に入力された行に対して選択をします（こうして、どの行が集約計算に入るかを制御しています）。これに対して<command>HAVING</command>は、グループ化と集約計算を行った後のグループの行に対して選択をします。したがって<command>WHERE</command>節は集約関数を含まないのです。つまり、どの行が集合への入力であるかについて決定するために集約を使用することは意味をなさないのです。逆に、<command>HAVING</command>節は常に集約関数を含みます（厳密にいうと、集約を使用しない<command>HAVING</command>節も記述できますが、効率がよくありません。同じ条件なら<command>WHERE</command>節を使うほうが効率的です）。
   </para>

   <para>
<!--    As an example, we can find the highest low-temperature reading anywhere
    with -->

    たとえば、最低気温の中で一番高いものを探すことができます。</para>

<programlisting>
SELECT max(temp_lo) FROM weather;
</programlisting>

<!--    If we want to know what city (or cities) that reading occurred in,
    we might try -->

<para>都市（複数かもしれません）に起こった事を知りたくて以下のような問い合わせを試してみるかもしれません。</para>

<programlisting>
SELECT city FROM weather WHERE temp_lo = max(temp_lo);
</programlisting>

<!--    but this will not work since the aggregate
    <function>max</function> can't be used in
    <command>WHERE</command>. However, as is often the case the query can be
    restated to accomplish the intended result; here by using a
    <firstterm>subselect</firstterm>: -->

<para>しかし集約の<function>max</function>は<command>WHERE</command>中で使うことができないので、この問い合わせは実行できません。しかしこの問い合わせのケースはよくありますので、問い合わせを書き直せば、意図した結果が得られます。これには<firstterm>subselect</firstterm>を使用します。</para>

<programlisting>
SELECT city FROM weather
    WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
</programlisting>

<!--    This is OK because the sub-select is an independent computation that
    computes its own aggregate separately from what's happening in the outer
    select.  -->

<para>内側の選択が、外側の選択で起こっていることから、別にそれ自身の集約を計算する独立した計算であるので、この問い合わせは可能です。
   </para>

   <para>
<!--    Aggregates are also very useful in combination with
    <command>GROUP BY</command> clauses.  For example, we can get the
    maximum low temperature observed in each city with -->

    集約は<command>GROUP BY</command>節を組み合わせると、より有効です。たとえば、それぞれの都市における最低気温を得たい場合、以下のようにすると都市ごとに1行が出力されます。</para>

<programlisting>
SELECT city, max(temp_lo)
    FROM weather
    GROUP BY city;
</programlisting>

<para><command>HAVING</command>を使用することでグループ分けした行に対してフィルタをかけることができます。</para>

<programlisting>
SELECT city, max(temp_lo)
    FROM weather
    GROUP BY city
    HAVING min(temp_lo) < 0;
</programlisting>

<!--    which gives us the same results for only the cities that have some
    below-zero readings.  Finally, if we only care about cities whose
    names begin with "<literal>P</literal>", we might do -->

<para>これは下記の0以下の値をもつ都市だけに対して同じ結果を返します。最後に、「P」で始まる都市のみを検索したいのであれば以下ようにします。</para>

<programlisting>
SELECT city, max(temp_lo)
    FROM weather
    WHERE city like 'P%'
    GROUP BY city
    HAVING min(temp_lo) < 0;
</programlisting>

<!--    Note that we can apply the city-name restriction in
    <command>WHERE</command>, since it needs no aggregate.  This is
    more efficient than adding the restriction to <command>HAVING</command>,
    because we avoid doing the grouping and aggregate calculations
    for all rows that fail the <command>WHERE</command> check. -->

<para>それ自体が集約を必要としないという理由から<command>WHERE</command>で都市名の制約を適用することができるという点に注意してください。これは、<command>HAVING</command>で制限をするよりも効果的です。それは、<command>WHERE</command>でひっかからないすべての行のためにグループ化と集計計算を行うことを避けられるからです。
   </para>
  </sect1>
 </chapter>

<!-- Keep this comment at the end of the file
Local variables:
mode:sgml
sgml-omittag:nil
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:"./reference.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:("/usr/lib/sgml/catalog")
sgml-local-ecat-files:nil
End:
-->
