head	1.49;
access;
symbols
	REL9_0_0:1.48.14.1
	REL9_1_ALPHA1:1.49
	REL9_0_RC1:1.48.14.1
	REL9_0_BETA4:1.48.14.1
	REL9_0_STABLE:1.48.0.14
	REL9_0_BETA3:1.48
	REL9_0_BETA2:1.48
	REL7_4_29:1.31
	REL8_0_25:1.33.4.1
	REL8_1_21:1.38
	REL8_2_17:1.42
	REL8_3_11:1.46
	REL8_4_4:1.48
	REL9_0_BETA1:1.48
	REL9_0_ALPHA5_BRANCH:1.48.0.12
	REL9_0_ALPHA5:1.48
	REL7_4_28:1.31
	REL8_0_24:1.33.4.1
	REL8_1_20:1.38
	REL8_2_16:1.42
	REL8_3_10:1.46
	REL8_4_3:1.48
	REL9_0_ALPHA4:1.48
	REL9_0_ALPHA4_BRANCH:1.48.0.10
	REL8_5_ALPHA3:1.48
	REL8_5_ALPHA3_BRANCH:1.48.0.8
	REL7_4_27:1.31
	REL8_0_23:1.33.4.1
	REL8_1_19:1.38
	REL8_2_15:1.42
	REL8_3_9:1.46
	REL8_4_2:1.48
	REL8_5_ALPHA2:1.48
	REL8_5_ALPHA2_BRANCH:1.48.0.6
	REL7_4_26:1.31
	REL8_0_22:1.33.4.1
	REL8_1_18:1.38
	REL8_2_14:1.42
	REL8_3_8:1.46
	REL8_4_1:1.48
	REL8_5_ALPHA1:1.48
	REL8_5_ALPHA1_BRANCH:1.48.0.4
	REL8_4_STABLE:1.48.0.2
	REL8_4_0:1.48
	REL8_4_RC2:1.48
	REL8_4_RC1:1.48
	REL8_4_BETA2:1.48
	REL8_4_BETA1:1.47
	REL7_4_25:1.31
	REL8_0_21:1.33.4.1
	REL8_1_17:1.38
	REL8_2_13:1.42
	REL8_3_7:1.46
	REL7_4_24:1.31
	REL8_0_20:1.33.4.1
	REL8_1_16:1.38
	REL8_2_12:1.42
	REL8_3_6:1.46
	REL7_4_23:1.31
	REL8_0_19:1.33.4.1
	REL8_1_15:1.38
	REL8_2_11:1.42
	REL8_3_5:1.46
	REL7_4_22:1.31
	REL8_0_18:1.33.4.1
	REL8_1_14:1.38
	REL8_2_10:1.42
	REL8_3_4:1.46
	REL7_4_21:1.31
	REL8_0_17:1.33.4.1
	REL8_1_13:1.38
	REL8_2_9:1.42
	REL8_3_3:1.46
	REL7_4_20:1.31
	REL8_0_16:1.33.4.1
	REL8_1_12:1.38
	REL8_2_8:1.42
	REL8_3_2:1.46
	REL8_2_7:1.42
	REL8_3_1:1.46
	REL8_3_STABLE:1.46.0.2
	REL8_3_0:1.46
	REL8_3_RC2:1.46
	REL7_3_21:1.27
	REL7_4_19:1.31
	REL8_0_15:1.33.4.1
	REL8_1_11:1.38
	REL8_2_6:1.42
	REL8_3_RC1:1.46
	REL8_3_BETA4:1.46
	REL8_3_BETA3:1.46
	REL8_3_BETA2:1.46
	REL8_3_BETA1:1.46
	REL7_3_20:1.27
	REL7_4_18:1.31
	REL8_0_14:1.33.4.1
	REL8_1_10:1.38
	REL8_2_5:1.42
	REL7_3_19:1.27
	REL7_4_17:1.31
	REL8_0_13:1.33.4.1
	REL8_1_9:1.38
	REL8_2_4:1.42
	REL8_0_12:1.33.4.1
	REL8_1_8:1.38
	REL8_2_3:1.42
	REL7_3_18:1.27
	REL7_4_16:1.31
	REL8_0_11:1.33.4.1
	REL8_1_7:1.38
	REL8_2_2:1.42
	REL8_0_10:1.33.4.1
	REL8_1_6:1.38
	REL8_2_1:1.42
	REL7_4_15:1.31
	REL7_3_17:1.27
	REL8_2_STABLE:1.42.0.2
	REL8_2_0:1.42
	REL8_2_RC1:1.42
	REL8_2_BETA3:1.42
	REL8_2_BETA2:1.42
	REL8_1_5:1.38
	REL8_0_9:1.33.4.1
	REL7_4_14:1.31
	REL7_3_16:1.27
	REL8_2_BETA1:1.42
	REL7_3_15:1.27
	REL7_4_13:1.31
	REL8_0_8:1.33.4.1
	REL8_1_4:1.38
	REL7_3_14:1.27
	REL7_4_12:1.31
	REL8_0_7:1.33.4.1
	REL8_1_3:1.38
	REL7_3_13:1.27
	REL7_4_11:1.31
	REL8_0_6:1.33.4.1
	REL8_1_2:1.38
	REL7_3_12:1.27
	REL7_4_10:1.31
	REL8_0_5:1.33.4.1
	REL8_1_1:1.38
	REL8_1_STABLE:1.38.0.2
	REL8_1_0:1.38
	REL8_1_0RC1:1.38
	REL8_1_0BETA4:1.38
	REL8_1_0BETA3:1.38
	REL7_3_11:1.27
	REL7_4_9:1.31
	REL8_0_4:1.33.4.1
	REL8_1_0BETA2:1.38
	REL8_1_0BETA1:1.38
	REL7_2_8:1.24
	REL7_3_10:1.27
	REL7_4_8:1.31
	REL8_0_3:1.33.4.1
	REL8_0_2:1.33.4.1
	REL7_2_7:1.24
	REL7_3_9:1.27
	REL7_4_7:1.31
	REL8_0_1:1.33.4.1
	REL8_0_STABLE:1.33.0.4
	REL8_0_0:1.33.0.2
	REL8_0_0RC5:1.33
	REL8_0_0RC4:1.33
	REL8_0_0RC3:1.33
	REL8_0_0RC2:1.33
	REL8_0_0RC1:1.33
	REL8_0_0BETA5:1.33
	REL8_0_0BETA4:1.32
	REL7_4_6:1.31
	REL7_3_8:1.27
	REL7_2_6:1.24
	REL8_0_0BETA3:1.32
	REL8_0_0BETA2:1.32
	REL7_2_5:1.24
	REL7_4_5:1.31
	REL7_3_7:1.27
	REL7_4_4:1.31
	REL8_0_0BETA1:1.32
	REL7_4_3:1.31
	REL7_4_2:1.31
	REL7_3_6:1.27
	REL7_4_1:1.31
	REL7_3_5:1.27
	REL7_4:1.31
	REL7_4_RC2:1.31
	REL7_4_STABLE:1.31.0.4
	REL7_4_RC1:1.31
	REL7_4_BETA5:1.31
	REL7_4_BETA4:1.31
	REL7_4_BETA3:1.31
	REL7_4_BETA2:1.31
	WIN32_DEV:1.31.0.2
	REL7_4_BETA1:1.30
	REL7_3_4:1.27
	REL7_3_2:1.27
	REL7_2_4:1.24
	REL7_3_STABLE:1.27.0.2
	REL7_2_3:1.24
	REL7_2_STABLE:1.24.0.2
	REL7_2:1.24
	REL7_2_RC2:1.24
	REL7_2_RC1:1.24
	REL7_2_BETA5:1.24
	REL7_2_BETA4:1.24
	REL7_2_BETA3:1.24
	REL7_2_BETA2:1.24
	REL7_2_BETA1:1.24
	REL7_1_2:1.20
	REL7_1_STABLE:1.20.0.2
	REL7_1_BETA:1.13
	REL7_1_BETA3:1.15
	REL7_1_BETA2:1.15
	REL7_1:1.20
	REL7_0_PATCHES:1.9.0.2
	REL7_0:1.9
	REL6_5_PATCHES:1.6.0.2
	REL6_5:1.6;
locks; strict;
comment	@# @;


1.49
date	2010.07.29.19.34.40;	author petere;	state Exp;
branches;
next	1.48;

1.48
date	2009.04.27.16.27.36;	author momjian;	state Exp;
branches
	1.48.14.1;
next	1.47;

1.47
date	2008.02.15.22.17.06;	author tgl;	state Exp;
branches;
next	1.46;

1.46
date	2007.02.16.03.50.29;	author momjian;	state Exp;
branches;
next	1.45;

1.45
date	2007.02.01.19.10.24;	author momjian;	state Exp;
branches;
next	1.44;

1.44
date	2007.01.31.20.56.19;	author momjian;	state Exp;
branches;
next	1.43;

1.43
date	2007.01.09.02.14.10;	author tgl;	state Exp;
branches;
next	1.42;

1.42
date	2006.09.16.00.30.15;	author momjian;	state Exp;
branches;
next	1.41;

1.41
date	2006.07.27.19.52.04;	author tgl;	state Exp;
branches;
next	1.40;

1.40
date	2006.04.30.18.30.38;	author tgl;	state Exp;
branches;
next	1.39;

1.39
date	2006.03.10.19.10.49;	author momjian;	state Exp;
branches;
next	1.38;

1.38
date	2005.08.01.20.31.05;	author tgl;	state Exp;
branches;
next	1.37;

1.37
date	2005.07.14.06.17.35;	author neilc;	state Exp;
branches;
next	1.36;

1.36
date	2005.04.28.21.47.09;	author tgl;	state Exp;
branches;
next	1.35;

1.35
date	2005.02.21.02.21.03;	author neilc;	state Exp;
branches;
next	1.34;

1.34
date	2005.01.22.22.56.36;	author momjian;	state Exp;
branches;
next	1.33;

1.33
date	2004.11.15.06.32.14;	author neilc;	state Exp;
branches
	1.33.4.1;
next	1.32;

1.32
date	2003.11.29.19.51.37;	author pgsql;	state Exp;
branches;
next	1.31;

1.31
date	2003.08.10.01.20.34;	author tgl;	state Exp;
branches;
next	1.30;

1.30
date	2003.03.27.16.51.26;	author momjian;	state Exp;
branches;
next	1.29;

1.29
date	2003.02.19.04.06.28;	author momjian;	state Exp;
branches;
next	1.28;

1.28
date	2003.01.15.18.01.05;	author momjian;	state Exp;
branches;
next	1.27;

1.27
date	2002.08.28.14.35.36;	author momjian;	state Exp;
branches;
next	1.26;

1.26
date	2002.03.15.16.16.31;	author momjian;	state Exp;
branches;
next	1.25;

1.25
date	2002.03.15.15.55.58;	author momjian;	state Exp;
branches;
next	1.24;

1.24
date	2001.10.23.16.42.36;	author momjian;	state Exp;
branches;
next	1.23;

1.23
date	2001.10.20.02.55.38;	author momjian;	state Exp;
branches;
next	1.22;

1.22
date	2001.09.23.03.39.01;	author momjian;	state Exp;
branches;
next	1.21;

1.21
date	2001.05.22.16.00.00;	author petere;	state Exp;
branches;
next	1.20;

1.20
date	2001.03.24.23.03.26;	author petere;	state Exp;
branches;
next	1.19;

1.19
date	2001.02.15.04.10.54;	author tgl;	state Exp;
branches;
next	1.18;

1.18
date	2001.01.27.05.07.28;	author momjian;	state Exp;
branches;
next	1.17;

1.17
date	2001.01.09.16.05.21;	author momjian;	state Exp;
branches;
next	1.16;

1.16
date	2001.01.09.15.48.18;	author momjian;	state Exp;
branches;
next	1.15;

1.15
date	2000.12.12.05.07.58;	author tgl;	state Exp;
branches;
next	1.14;

1.14
date	2000.12.09.22.59.25;	author momjian;	state Exp;
branches;
next	1.13;

1.13
date	2000.11.29.20.15.59;	author petere;	state Exp;
branches;
next	1.12;

1.12
date	2000.09.29.20.21.34;	author petere;	state Exp;
branches;
next	1.11;

1.11
date	2000.06.20.18.04.18;	author momjian;	state Exp;
branches;
next	1.10;

1.10
date	2000.06.14.13.10.48;	author thomas;	state Exp;
branches;
next	1.9;

1.9
date	2000.05.02.20.01.52;	author thomas;	state Exp;
branches
	1.9.2.1;
next	1.8;

1.8
date	2000.04.07.13.30.58;	author thomas;	state Exp;
branches;
next	1.7;

1.7
date	2000.03.31.03.27.41;	author thomas;	state Exp;
branches;
next	1.6;

1.6
date	99.05.26.17.30.30;	author thomas;	state Exp;
branches;
next	1.5;

1.5
date	99.05.22.02.27.24;	author thomas;	state Exp;
branches;
next	1.4;

1.4
date	99.05.20.05.39.28;	author thomas;	state Exp;
branches;
next	1.3;

1.3
date	99.05.04.02.18.34;	author thomas;	state Exp;
branches;
next	1.2;

1.2
date	99.03.19.02.41.35;	author momjian;	state Exp;
branches;
next	1.1;

1.1
date	99.01.19.16.09.16;	author thomas;	state Exp;
branches;
next	;

1.9.2.1
date	2000.06.14.13.18.59;	author thomas;	state Exp;
branches;
next	;

1.33.4.1
date	2005.01.22.23.05.50;	author momjian;	state Exp;
branches;
next	;

1.48.14.1
date	2010.07.29.19.34.37;	author petere;	state Exp;
branches;
next	;


desc
@@


1.49
log
@Fix indentation of verbatim block elements

Block elements with verbatim formatting (literallayout, programlisting,
screen, synopsis) should be aligned at column 0 independent of the surrounding
SGML, because whitespace is significant, and indenting them creates erratic
whitespace in the output.  The CSS stylesheets already take care of indenting
the output.

Assorted markup improvements to go along with it.
@
text
@<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.48 2009/04/27 16:27:36 momjian Exp $ -->

 <chapter id="sql-intro">
  <title>SQL</title>

  <abstract>
   <para>
    This chapter introduces the mathematical concepts behind
    relational databases. It is not required reading, so if you bog
    down or want to get straight to some simple examples feel free to
    jump ahead to the next chapter and come back when you have more
    time and patience. This stuff is supposed to be fun!
   </para>

   <para>
    This material originally appeared as a part of
    Stefan Simkovics' Master's Thesis
    (<xref linkend="SIM98" endterm="SIM98">).
   </para>
  </abstract>

  <para>
   <acronym>SQL</acronym> has become the most popular relational query 
   language.
   The name <quote><acronym>SQL</acronym></quote> is an abbreviation for
   <firstterm>Structured Query Language</firstterm>. 
   In 1974 Donald Chamberlin and others defined the
   language SEQUEL (<firstterm>Structured English Query
    Language</firstterm>) at IBM
   Research. This language was first implemented in an IBM
   prototype called SEQUEL-XRM in 1974-75. In 1976-77 a revised version
   of SEQUEL called SEQUEL/2 was defined and the name was changed to
   <acronym>SQL</acronym>
   subsequently.
  </para>

  <para>
   A new prototype called System R was developed by IBM in 1977. System R
   implemented a large subset of SEQUEL/2 (now <acronym>SQL</acronym>)
   and a number of
   changes were made to <acronym>SQL</acronym> during the project.
   System R was installed in
   a number of user sites, both internal IBM sites and also some selected
   customer sites. Thanks to the success and acceptance of System R at
   those user sites IBM started to develop commercial products that
   implemented the <acronym>SQL</acronym> language based on the System
   R technology.
  </para>

  <para>
   Over the next years IBM and also a number of other vendors announced
   <acronym>SQL</acronym> products such as
   <productname>SQL/DS</productname> (IBM),
   <productname>DB2</productname> (IBM),
   <productname>ORACLE</productname> (Oracle Corp.),
   <productname>DG/SQL</productname> (Data General Corp.),
   and <productname>SYBASE</productname> (Sybase Inc.).
  </para>

  <para>
   <acronym>SQL</acronym> is also an official standard now. In 1982
   the American National
   Standards Institute (<acronym>ANSI</acronym>) chartered its
   Database Committee X3H2 to
   develop a proposal for a standard relational language. This proposal
   was ratified in 1986 and consisted essentially of the IBM dialect of
   <acronym>SQL</acronym>. In 1987 this <acronym>ANSI</acronym> 
   standard was also accepted as an international
   standard by the International Organization for Standardization
   (<acronym>ISO</acronym>).
   This original standard version of <acronym>SQL</acronym> is often
   referred to,
   informally, as <quote><abbrev>SQL/86</abbrev></quote>. In 1989 the original
   standard was extended
   and this new standard is often, again informally, referred to as
   <quote><abbrev>SQL/89</abbrev></quote>. Also in 1989, a related standard called
   <firstterm>Database Language Embedded <acronym>SQL</acronym></firstterm>
   (<acronym>ESQL</acronym>) was developed.
  </para>

  <para>
   The <acronym>ISO</acronym> and <acronym>ANSI</acronym> committees
   have been working for many years on the
   definition of a greatly expanded version of the original standard,
   referred to informally as <firstterm><acronym>SQL2</acronym></firstterm>
   or <firstterm><acronym>SQL/92</acronym></firstterm>. This version became a
   ratified standard - <quote>International Standard ISO/IEC 9075:1992,
   Database Language <acronym>SQL</acronym></quote> - in late 1992.
   <acronym>SQL/92</acronym> is the version
   normally meant when people refer to <quote>the <acronym>SQL</acronym>
   standard</quote>. A detailed
   description of <acronym>SQL/92</acronym> is given in 
   <xref linkend="DATE97" endterm="DATE97">. At the time of
   writing this document a new standard informally referred to
   as <firstterm><acronym>SQL3</acronym></firstterm>
   is under development. It is planned to make <acronym>SQL</acronym>
   a Turing-complete
   language, i.e., all computable queries (e.g., recursive queries) will be
   possible. This has now been completed as SQL:2003.
  </para>

  <sect1 id="rel-model">
   <title>The Relational Data Model</title>

  <para>
    As mentioned before, <acronym>SQL</acronym> is a relational
    language. That means it is
    based on the <firstterm>relational data model</firstterm>
    first published by E.F. Codd in
    1970. We will give a formal description of the relational model
    later (in
    <xref linkend="formal-notion" endterm="formal-notion">)
    but first we want to have a look at it from a more intuitive
    point of view.
  </para>

  <para>
    A <firstterm>relational database</firstterm> is a database that is 
    perceived by its
    users as a <firstterm>collection of tables</firstterm> (and
    nothing else but tables).
    A table consists of rows and columns where each row represents a
    record and each column represents an attribute of the records
    contained in the table.
    <xref linkend="supplier-fig" endterm="supplier-fig">
    shows an example of a database consisting of three tables:

    <itemizedlist>
     <listitem>
      <para>
       SUPPLIER is a table storing the number
       (SNO), the name (SNAME) and the city (CITY) of a supplier.
      </para>
     </listitem>

     <listitem>
      <para>
       PART is a table storing the number (PNO) the name (PNAME) and
       the price (PRICE) of a part.
      </para>
     </listitem>

     <listitem>
      <para>
       SELLS stores information about which part (PNO) is sold by which
       supplier (SNO). 
       It serves in a sense to connect the other two tables together.
      </para>
     </listitem>
    </itemizedlist>

    <example>
     <title id="supplier-fig">The Suppliers and Parts Database</title>
<screen>
SUPPLIER:                   SELLS:
 SNO |  SNAME  |  CITY       SNO | PNO
----+---------+--------     -----+-----
 1  |  Smith  | London        1  |  1
 2  |  Jones  | Paris         1  |  2
 3  |  Adams  | Vienna        2  |  4
 4  |  Blake  | Rome          3  |  1
                              3  |  3
                              4  |  2
PART:                         4  |  3
 PNO |  PNAME  |  PRICE       4  |  4
----+---------+---------
 1  |  Screw  |   10
 2  |  Nut    |    8
 3  |  Bolt   |   15
 4  |  Cam    |   25
</screen>
    </example>
   </para>

   <para>
    The tables PART and SUPPLIER can be regarded as
    <firstterm>entities</firstterm> and
    SELLS can be regarded as a <firstterm>relationship</firstterm>
    between a particular
    part and a particular supplier. 
   </para>

   <para>
    As we will see later, <acronym>SQL</acronym> operates on tables
    like the ones just
    defined but before that we will study the theory of the relational
    model.
   </para>
  </sect1>

  <sect1 id="relmodel-formal">
   <title id="formal-notion">Relational Data Model Formalities</title>

   <para>
    The mathematical concept underlying the relational model is the
    set-theoretic <firstterm>relation</firstterm> which is a subset of
    the Cartesian
    product of a list of domains. This set-theoretic relation gives
    the model its name (do not confuse it with the relationship from the
    <firstterm>Entity-Relationship model</firstterm>).
    Formally a domain is simply a set of
    values. For example the set of integers is a domain. Also the set of
    character strings of length 20 and the real numbers are examples of
    domains.
   </para>

   <para>
<!--
\begin{definition}
The <firstterm>Cartesian product</firstterm> of domains $D_{1},
    D_{2},\ldots, D_{k}$ written
\mbox{$D_{1} \times D_{2} \times \ldots \times D_{k}$} is the set of
all $k$-tuples $(v_{1},v_{2},\ldots,v_{k})$ such that \mbox{$v_{1} \in
D_{1}, v_{2} \in D_{2}, \ldots, v_{k} \in D_{k}$}.
\end{definition}
-->
    The <firstterm>Cartesian product</firstterm> of domains
    <parameter>D<subscript>1</subscript></parameter>,
    <parameter>D<subscript>2</subscript></parameter>,
    ...
    <parameter>D<subscript>k</subscript></parameter>,
    written
    <parameter>D<subscript>1</subscript></parameter> &times;
    <parameter>D<subscript>2</subscript></parameter> &times;
    ... &times;
    <parameter>D<subscript>k</subscript></parameter>
    is the set of all k-tuples
    <parameter>v<subscript>1</subscript></parameter>,
    <parameter>v<subscript>2</subscript></parameter>,
    ...
    <parameter>v<subscript>k</subscript></parameter>,
    such that
    <parameter>v<subscript>1</subscript></parameter> &isin; 
    <parameter>D<subscript>1</subscript></parameter>,
    <parameter>v<subscript>2</subscript></parameter> &isin; 
    <parameter>D<subscript>2</subscript></parameter>,
    ...
    <parameter>v<subscript>k</subscript></parameter> &isin; 
    <parameter>D<subscript>k</subscript></parameter>.
   </para>

   <para>
    For example, when we have
<!--
 $k=2$, $D_{1}=\{0,1\}$ and
$D_{2}=\{a,b,c\}$, then $D_{1} \times D_{2}$ is
$\{(0,a),(0,b),(0,c),(1,a),(1,b),(1,c)\}$.
-->
    <parameter>k</parameter>=2,
    <parameter>D<subscript>1</subscript></parameter>=<literal>{0,1}</literal> and
    <parameter>D<subscript>2</subscript></parameter>=<literal>{a,b,c}</literal> then
    <parameter>D<subscript>1</subscript></parameter> &times;
    <parameter>D<subscript>2</subscript></parameter> is
    <literal>{(0,a),(0,b),(0,c),(1,a),(1,b),(1,c)}</literal>.
   </para>

   <para>
<!--
\begin{definition}
A Relation is any subset of the Cartesian product of one or more
domains: $R \subseteq$ \mbox{$D_{1} \times D_{2} \times \ldots \times D_{k}$}
\end{definition}
-->
    A Relation is any subset of the Cartesian product of one or more
    domains: <parameter>R</parameter> &sube;
    <parameter>D<subscript>1</subscript></parameter> &times;
    <parameter>D<subscript>2</subscript></parameter> &times;
    ... &times;
    <parameter>D<subscript>k</subscript></parameter>.
   </para>

   <para>
    For example <literal>{(0,a),(0,b),(1,a)}</literal> is a relation;
    it is in fact a subset of
    <parameter>D<subscript>1</subscript></parameter> &times;
    <parameter>D<subscript>2</subscript></parameter>
    mentioned above.
   </para>

   <para>
    The members of a relation are called tuples. Each relation of some
    Cartesian product
    <parameter>D<subscript>1</subscript></parameter> &times;
    <parameter>D<subscript>2</subscript></parameter> &times;
    ... &times;
    <parameter>D<subscript>k</subscript></parameter>
    is said to have arity <literal>k</literal> and is therefore a set
    of <literal>k</literal>-tuples.
   </para>

   <para>
    A relation can be viewed as a table (as we already did, remember
    <xref linkend="supplier-fig" endterm="supplier-fig"> where
    every tuple is represented by a row and every column corresponds to
    one component of a tuple. Giving names (called attributes) to the
    columns leads to the definition of a 
    <firstterm>relation scheme</firstterm>.
   </para>

   <para>
<!--
\begin{definition}
A {\it relation scheme} $R$ is a finite set of attributes
\mbox{$\{A_{1},A_{2},\ldots,A_{k}\}$}. There is a domain $D_{i}$ for
each attribute $A_{i}, 1 \le i \le k$ where the values of the
attributes are taken from. We often write a relation scheme as
\mbox{$R(A_{1},A_{2},\ldots,A_{k})$}.
\end{definition}
-->
    A <firstterm>relation scheme</firstterm> <literal>R</literal> is a 
    finite set of attributes
    <parameter>A<subscript>1</subscript></parameter>,
    <parameter>A<subscript>2</subscript></parameter>,
    ...
    <parameter>A<subscript>k</subscript></parameter>.
    There is a domain
    <parameter>D<subscript>i</subscript></parameter>,
    for each attribute
    <parameter>A<subscript>i</subscript></parameter>,
    1 &lt;= <literal>i</literal> &lt;= <literal>k</literal>,
    where the values of the attributes are taken from. We often write
    a relation scheme as
    <literal>R(<parameter>A<subscript>1</subscript></parameter>,
    <parameter>A<subscript>2</subscript></parameter>,
    ...
    <parameter>A<subscript>k</subscript></parameter>)</literal>.

    <note>
     <para>
      A <firstterm>relation scheme</firstterm> is just a kind of template
      whereas a <firstterm>relation</firstterm> is an instance of a
      <firstterm>relation
       scheme</firstterm>. The relation consists of tuples (and can
      therefore be
      viewed as a table); not so the relation scheme.
     </para>
    </note>
   </para>

   <sect2>
    <title id="domains">Domains vs. Data Types</title>

    <para>
     We often talked about <firstterm>domains</firstterm>
     in the last section. Recall that a
     domain is, formally, just a set of values (e.g., the set of integers or
     the real numbers). In terms of database systems we often talk of
     <firstterm>data types</firstterm> instead of domains.
     When we define a table we have to make
     a decision about which attributes to include. Additionally we
     have to decide which kind of data is going to be stored as
     attribute values. For example the values of
     <classname>SNAME</classname> from the table
     <classname>SUPPLIER</classname> will be character strings,
     whereas <classname>SNO</classname> will store
     integers. We define this by assigning a data type to each
     attribute. The type of <classname>SNAME</classname> will be
     <type>VARCHAR(20)</type> (this is the <acronym>SQL</acronym> type
     for character strings of length &lt;= 20),
     the type of <classname>SNO</classname> will be
     <type>INTEGER</type>. With the assignment of a data type we also
     have selected
     a domain for an attribute. The domain of
     <classname>SNAME</classname> is the set of all
     character strings of length &lt;= 20,
     the domain of <classname>SNO</classname> is the set of
     all integer numbers.
    </para>
   </sect2>
  </sect1>

  <sect1 id="relmodel-oper">
   <title id="operations">Operations in the Relational Data Model</title>

   <para>
    In the previous section
    (<xref linkend="formal-notion" endterm="formal-notion">)
    we defined the mathematical notion of
    the relational model. Now we know how the data can be stored using a
    relational data model but we do not know what to do with all these
    tables to retrieve something from the database yet. For example somebody
    could ask for the names of all suppliers that sell the part
    'Screw'. Therefore two rather different kinds of notations for
    expressing operations on relations have been defined:

    <itemizedlist>
     <listitem>
      <para>
       The <firstterm>Relational Algebra</firstterm> which is an
       algebraic notation,
       where queries are expressed by applying specialized operators to the
       relations.
      </para>
     </listitem>

     <listitem>
      <para>
       The <firstterm>Relational Calculus</firstterm> which is a
       logical notation,
       where queries are expressed by formulating some logical restrictions
       that the tuples in the answer must satisfy.
      </para>
    </listitem>
    </itemizedlist>
   </para>

   <sect2>
    <title id="rel-alg">Relational Algebra</title>

    <para>
     The <firstterm>Relational Algebra</firstterm> was introduced by
     E. F. Codd in 1972. It consists of a set of operations on relations:

     <itemizedlist>
      <listitem>
       <para>
        SELECT (&sigma;): extracts <firstterm>tuples</firstterm> from
        a relation that
        satisfy a given restriction. Let <parameter>R</parameter> be a 
        table that contains an attribute
        <parameter>A</parameter>.
&sigma;<subscript>A=a</subscript>(R) = {t &isin; R &mid; t(A) = a}
        where <literal>t</literal> denotes a
        tuple of <parameter>R</parameter> and <literal>t(A)</literal>
        denotes the value of attribute <parameter>A</parameter> of
        tuple <literal>t</literal>.
       </para>
      </listitem>

      <listitem>
       <para>
        PROJECT (&pi;): extracts specified
        <firstterm>attributes</firstterm> (columns) from a
        relation. Let <classname>R</classname> be a relation
        that contains an attribute <classname>X</classname>.
        &pi;<subscript>X</subscript>(<classname>R</classname>) = {t(X) &mid; t &isin; <classname>R</classname>},
        where <literal>t</literal>(<classname>X</classname>) denotes the value of
        attribute <classname>X</classname> of tuple <literal>t</literal>.
       </para>
      </listitem>

      <listitem>
       <para>
        PRODUCT (&times;): builds the Cartesian product of two
        relations. Let <classname>R</classname> be a table with arity
        <literal>k</literal><subscript>1</subscript> and let
        <classname>S</classname> be a table with
        arity <literal>k</literal><subscript>2</subscript>.
        <classname>R</classname> &times; <classname>S</classname>
        is the set of all 
        <literal>k</literal><subscript>1</subscript>
        + <literal>k</literal><subscript>2</subscript>-tuples
        whose first <literal>k</literal><subscript>1</subscript>
        components form a tuple in <classname>R</classname> and whose last
        <literal>k</literal><subscript>2</subscript> components form a
        tuple in <classname>S</classname>.
       </para>
      </listitem>

      <listitem>
       <para>
        UNION (&cup;): builds the set-theoretic union of two
        tables. Given the tables <classname>R</classname> and
        <classname>S</classname> (both must have the same arity),
        the union <classname>R</classname> &cup; <classname>S</classname>
        is the set of tuples that are in <classname>R</classname>
        or <classname>S</classname> or both.
       </para>
      </listitem>

      <listitem>
       <para>
        INTERSECT (&cap;): builds the set-theoretic intersection of two
        tables. Given the tables <classname>R</classname> and
        <classname>S</classname>,
        <classname>R</classname> &cap; <classname>S</classname> is the
        set of tuples
        that are in <classname>R</classname> and in
        <classname>S</classname>.
        We again require that <classname>R</classname> and 
        <classname>S</classname> have the
        same arity.
       </para>
      </listitem>

      <listitem>
       <para>
        DIFFERENCE (&minus; or &setmn;): builds the set difference of
        two tables. Let <classname>R</classname> and <classname>S</classname>
        again be two tables with the same
        arity. <classname>R</classname> - <classname>S</classname>
        is the set of tuples in <classname>R</classname> but not in
        <classname>S</classname>.
       </para>
      </listitem>

      <listitem>
       <para>
        JOIN (&prod;): connects two tables by their common
        attributes. Let <classname>R</classname> be a table with the 
        attributes <classname>A</classname>,<classname>B</classname> 
        and <classname>C</classname> and
        let <classname>S</classname> be a table with the attributes
        <classname>C</classname>,<classname>D</classname>
        and <classname>E</classname>. There is one
        attribute common to both relations,
        the attribute <classname>C</classname>. 
<!--
        <classname>R</classname> &prod; <classname>S</classname> =
        &pi;<subscript><classname>R</classname>.<classname>A</classname>,<classname>R</classname>.<classname>B</classname>,<classname>R</classname>.<classname>C</classname>,<classname>S</classname>.<classname>D</classname>,<classname>S</classname>.<classname>E</classname></subscript>(&sigma;<subscript><classname>R</classname>.<classname>C</classname>=<classname>S</classname>.<classname>C</classname></subscript>(<classname>R</classname> &times; <classname>S</classname>)).
-->
        R &prod; S = &pi;<subscript>R.A,R.B,R.C,S.D,S.E</subscript>(&sigma;<subscript>R.C=S.C</subscript>(R &times; S)).
        What are we doing here? We first calculate the Cartesian
        product
        <classname>R</classname> &times; <classname>S</classname>.
        Then we select those tuples whose values for the common
        attribute <classname>C</classname> are equal
        (&sigma;<subscript>R.C = S.C</subscript>).
        Now we have a table
        that contains the attribute <classname>C</classname>
        two times and we correct this by
        projecting out the duplicate column.
       </para>

       <example>
        <title id="join-example">An Inner Join</title>

        <para>
         Let's have a look at the tables that are produced by evaluating the steps
         necessary for a join.
         Let the following two tables be given:

<screen>
R:                 S:
 A | B | C          C | D | E
---+---+---        ---+---+---
 1 | 2 | 3          3 | a | b
 4 | 5 | 6          6 | c | d
 7 | 8 | 9
</screen>
        </para>
       </example>

       <para>
        First we calculate the Cartesian product
        <classname>R</classname> &times; <classname>S</classname> and
        get:

<screen>
R x S:
 A | B | R.C | S.C | D | E
---+---+-----+-----+---+---
 1 | 2 |  3  |  3  | a | b
 1 | 2 |  3  |  6  | c | d
 4 | 5 |  6  |  3  | a | b
 4 | 5 |  6  |  6  | c | d
 7 | 8 |  9  |  3  | a | b
 7 | 8 |  9  |  6  | c | d
</screen>
       </para>

       <para>
        After the selection
        &sigma;<subscript>R.C=S.C</subscript>(R &times; S)
        we get:

<screen>
 A | B | R.C | S.C | D | E
---+---+-----+-----+---+---
 1 | 2 |  3  |  3  | a | b
 4 | 5 |  6  |  6  | c | d
</screen>
       </para>

       <para>
        To remove the duplicate column
        <classname>S</classname>.<classname>C</classname>
        we project it out by the following operation:
        &pi;<subscript>R.A,R.B,R.C,S.D,S.E</subscript>(&sigma;<subscript>R.C=S.C</subscript>(R &times; S))
        and get:

<screen>
 A | B | C | D | E
---+---+---+---+---
 1 | 2 | 3 | a | b
 4 | 5 | 6 | c | d
</screen>
       </para>
      </listitem>

      <listitem>
       <para>
        DIVIDE (&divide;): Let <classname>R</classname> be a table
        with the attributes A, B, C, and D and let
        <classname>S</classname> be a table with the attributes
        C and D.
        Then we define the division as:

<programlisting>
R &divide; S = {t &mid; &forall; t<subscript>s</subscript> &isin; S &exist; t<subscript>r</subscript> &isin; R
</programlisting>

        such that
t<subscript>r</subscript>(A,B)=t&and;t<subscript>r</subscript>(C,D)=t<subscript>s</subscript>}
        where
        t<subscript>r</subscript>(x,y)
        denotes a
        tuple of table <classname>R</classname> that consists only of
        the components <literal>x</literal> and <literal>y</literal>.
        Note that the tuple <literal>t</literal> only consists of the
        components <classname>A</classname> and
        <classname>B</classname> of relation <classname>R</classname>.
       </para>

       <para id="divide-example">
        Given the following tables

<screen>
R:                    S:
 A | B | C | D         C | D
---+---+---+---       ---+---
 a | b | c | d         c | d
 a | b | e | f         e | f
 b | c | e | f
 e | d | c | d
 e | d | e | f
 a | b | d | e
</screen>

        R &divide; S
        is derived as

<screen>
 A | B
---+---
 a | b
 e | d
</screen>
       </para>
      </listitem>
     </itemizedlist>
    </para>

    <para>
     For a more detailed description and definition of the relational
     algebra refer to [<xref linkend="ULL88" endterm="ULL88">] or
     [<xref linkend="DATE04" endterm="DATE04">].
    </para>

    <example>
     <title id="suppl-rel-alg">A Query Using Relational Algebra</title>
     <para>
      Recall that we formulated all those relational operators to be able to
      retrieve data from the database. Let's return to our example from 
      the previous
      section (<xref linkend="operations" endterm="operations">)
      where someone wanted to know the names of all
      suppliers that sell the part <literal>Screw</literal>. 
      This question can be answered
      using relational algebra by the following operation:

<programlisting>
&pi;<subscript>SUPPLIER.SNAME</subscript>(&sigma;<subscript>PART.PNAME='Screw'</subscript>(SUPPLIER &prod; SELLS &prod; PART))
</programlisting>
     </para>

     <para>
      We call such an operation a query. If we evaluate the above query
      against the our example tables
      (<xref linkend="supplier-fig" endterm="supplier-fig">)
      we will obtain the following result:

<screen>
 SNAME
-------
 Smith
 Adams
</screen>
     </para>
    </example>
   </sect2>

   <sect2 id="rel-calc">
    <title>Relational Calculus</title>

    <para>
     The relational calculus is based on the
     <firstterm>first order logic</firstterm>. There are
     two variants of the relational calculus:

     <itemizedlist>
      <listitem>
       <para>
        The <firstterm>Domain Relational Calculus</firstterm>
        (<acronym>DRC</acronym>), where variables
        stand for components (attributes) of the tuples.
       </para>
      </listitem>

      <listitem>
       <para>
        The <firstterm>Tuple Relational Calculus</firstterm>
        (<acronym>TRC</acronym>), where variables stand for tuples.
       </para>
      </listitem>
     </itemizedlist>
    </para>

    <para>
     We want to discuss the tuple relational calculus only because it is
     the one underlying the most relational languages. For a detailed
     discussion on <acronym>DRC</acronym> (and also
     <acronym>TRC</acronym>) see
     <xref linkend="DATE04" endterm="DATE04">
     or
     <xref linkend="ULL88" endterm="ULL88">.
    </para>
   </sect2>

   <sect2>
    <title>Tuple Relational Calculus</title>

    <para>
     The queries used in <acronym>TRC</acronym> are of the following
     form:

<programlisting>
x(A) &mid; F(x)
</programlisting>

     where <literal>x</literal> is a tuple variable
     <classname>A</classname> is a set of attributes and <literal>F</literal> is a
     formula. The resulting relation consists of all tuples
     <literal>t(A)</literal> that satisfy <literal>F(t)</literal>.
    </para>

    <para>
     If we want to answer the question from example
     <xref linkend="suppl-rel-alg" endterm="suppl-rel-alg">
     using <acronym>TRC</acronym> we formulate the following query:

<programlisting>
{x(SNAME) &mid; x &isin; SUPPLIER &and;
    &exist; y &isin; SELLS &exist; z &isin; PART (y(SNO)=x(SNO) &and;
    z(PNO)=y(PNO) &and;
    z(PNAME)='Screw')}
</programlisting>
    </para>

    <para>
     Evaluating the query against the tables from
     <xref linkend="supplier-fig" endterm="supplier-fig">
     again leads to the same result
     as in
     <xref linkend="suppl-rel-alg" endterm="suppl-rel-alg">.
    </para>
   </sect2>

   <sect2 id="alg-vs-calc">
    <title>Relational Algebra vs. Relational Calculus</title>

    <para>
     The relational algebra and the relational calculus have the same
     <firstterm>expressive power</firstterm>; i.e., all queries that
     can be formulated using relational algebra can also be formulated 
     using the relational calculus and vice versa.
     This was first proved by E. F. Codd in
     1972. This proof is based on an algorithm (<quote>Codd's reduction
     algorithm</quote>) by which an arbitrary expression of the relational
     calculus can be reduced to a semantically equivalent expression of
     relational algebra. For a more detailed discussion on that refer to
     <xref linkend="DATE04" endterm="DATE04">
     and
     <xref linkend="ULL88" endterm="ULL88">.
    </para>

    <para>
     It is sometimes said that languages based on the relational
     calculus are <quote>higher level</quote> or <quote>more
     declarative</quote> than languages based on relational algebra
     because the algebra (partially) specifies the order of operations
     while the calculus leaves it to a compiler or interpreter to
     determine the most efficient order of evaluation.
    </para>
   </sect2>
  </sect1>

  <sect1 id="sql-language">
   <title>The <acronym>SQL</acronym> Language</title>

   <para>
    As is the case with most modern relational languages,
    <acronym>SQL</acronym> is based on the tuple
    relational calculus. As a result every query that can be formulated
    using the tuple relational calculus (or equivalently, relational
    algebra) can also be formulated using
    <acronym>SQL</acronym>. There are, however,
    capabilities beyond the scope of relational algebra or calculus. Here
    is a list of some additional features provided by
    <acronym>SQL</acronym> that are not
    part of relational algebra or calculus:

    <itemizedlist>
     <listitem>
      <para>
       Commands for insertion, deletion or modification of data.
      </para>
     </listitem>

     <listitem>
      <para>
       Arithmetic capability: In <acronym>SQL</acronym> it is possible
       to involve
       arithmetic operations as well as comparisons, e.g.:

<programlisting>
A &lt; B + 3.
</programlisting>

       Note
       that + or other arithmetic operators appear neither in relational
       algebra nor in relational calculus.
      </para>
     </listitem>

     <listitem>
      <para>
       Assignment and Print Commands: It is possible to print a
       relation constructed by a query and to assign a computed relation to a
       relation name.
      </para>
     </listitem>

     <listitem>
      <para>
       Aggregate Functions: Operations such as
       <firstterm>average</firstterm>, <firstterm>sum</firstterm>,
       <firstterm>max</firstterm>, etc. can be applied to columns of a 
       relation to
       obtain a single quantity.
      </para>
     </listitem>
    </itemizedlist>
   </para>

   <sect2 id="select">
    <title id="select-title">Select</title>

    <para>
     The most often used command in <acronym>SQL</acronym> is the
     <command>SELECT</command> statement,
     used to retrieve data. The syntax is:

<synopsis>
SELECT [ ALL | DISTINCT [ ON ( <replaceable class="PARAMETER">expression</replaceable> [, ...] ) ] ]
    * | <replaceable class="PARAMETER">expression</replaceable> [ [ AS ] <replaceable class="PARAMETER">output_name</replaceable> ] [, ...]
    [ INTO [ TEMPORARY | TEMP ] [ TABLE ] <replaceable class="PARAMETER">new_table</replaceable> ]
    [ FROM <replaceable class="PARAMETER">from_item</replaceable> [, ...] ]
    [ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
    [ GROUP BY <replaceable class="PARAMETER">expression</replaceable> [, ...] ]
    [ HAVING <replaceable class="PARAMETER">condition</replaceable> [, ...] ]
    [ { UNION | INTERSECT | EXCEPT } [ ALL ] <replaceable class="PARAMETER">select</replaceable> ]
    [ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
    [ LIMIT { <replaceable class="PARAMETER">count</replaceable> | ALL } ]
    [ OFFSET <replaceable class="PARAMETER">start</replaceable> ]
    [ FOR { UPDATE | SHARE } [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT ] [...] ]
</synopsis>
    </para>

    <para>
     Now we will illustrate the complex syntax of the
     <command>SELECT</command> statement with various examples. The
     tables used for the examples are defined in <xref
     linkend="supplier-fig" endterm="supplier-fig">.
    </para>

    <sect3>
     <title>Simple Selects</title>

     <para>
      Here are some simple examples using a <command>SELECT</command> statement:

      <example>
       <title id="simple-query">Simple Query with Qualification</title>
       <para>
        To retrieve all tuples from table PART where the attribute PRICE is
        greater than 10 we formulate the following query:

<programlisting>
SELECT * FROM PART
    WHERE PRICE &gt; 10;
</programlisting>

        and get the table:

<screen>
 PNO |  PNAME  |  PRICE
-----+---------+--------
  3  |  Bolt   |   15
  4  |  Cam    |   25
</screen>
       </para>

       <para>
        Using <quote>*</quote> in the <command>SELECT</command> statement
        will deliver all attributes from the table. If we want to retrieve
        only the attributes PNAME and PRICE from table PART we use the
        statement:

<programlisting>
SELECT PNAME, PRICE 
    FROM PART
    WHERE PRICE &gt; 10;
</programlisting>

        In this case the result is:

<screen>
                      PNAME  |  PRICE
                     --------+--------
                      Bolt   |   15
                      Cam    |   25
</screen>

        Note that the <acronym>SQL</acronym> <command>SELECT</command>
        corresponds to the <quote>projection</quote> in relational algebra
        not to the <quote>selection</quote> (see <xref linkend="rel-alg"
        endterm="rel-alg"> for more details).
       </para>

       <para>
        The qualifications in the WHERE clause can also be logically connected
        using the keywords OR, AND, and NOT:

<programlisting>
SELECT PNAME, PRICE 
    FROM PART
    WHERE PNAME = 'Bolt' AND
         (PRICE = 0 OR PRICE &lt;= 15);
</programlisting>

        will lead to the result:

<screen>
 PNAME  |  PRICE
--------+--------
 Bolt   |   15
</screen>
       </para>

       <para>
        Arithmetic operations can be used in the target list and in the WHERE
        clause. For example if we want to know how much it would cost if we
        take two pieces of a part we could use the following query:

<programlisting>
SELECT PNAME, PRICE * 2 AS DOUBLE
    FROM PART
    WHERE PRICE * 2 &lt; 50;
</programlisting>

        and we get:

<screen>
 PNAME  |  DOUBLE
--------+---------
 Screw  |    20
 Nut    |    16
 Bolt   |    30
</screen>

        Note that the word DOUBLE after the keyword AS is the new title of the
        second column. This technique can be used for every element of the
        target list to assign a new title to the resulting
        column. This new title
        is often referred to as alias. The alias cannot be used throughout the
        rest of the query.
       </para>
      </example>
     </para>
    </sect3>

    <sect3>
     <title>Joins</title>

     <para id="simple-join">
      The following example shows how <firstterm>joins</firstterm> are
      realized in <acronym>SQL</acronym>.
     </para>

     <para>
      To join the three tables SUPPLIER, PART and SELLS over their common
      attributes we formulate the following statement:

<programlisting>
SELECT S.SNAME, P.PNAME
    FROM SUPPLIER S, PART P, SELLS SE
    WHERE S.SNO = SE.SNO AND
          P.PNO = SE.PNO;
</programlisting>

      and get the following table as a result:

<screen>
 SNAME | PNAME
-------+-------
 Smith | Screw
 Smith | Nut
 Jones | Cam
 Adams | Screw
 Adams | Bolt
 Blake | Nut
 Blake | Bolt
 Blake | Cam
</screen>
     </para>

     <para>
      In the FROM clause we introduced an alias name for every relation
      because there are common named attributes (SNO and PNO) among the
      relations. Now we can distinguish between the common named attributes
      by simply prefixing the attribute name with the alias name followed by
      a dot. The join is calculated in the same way as shown in 
      <xref linkend="join-example" endterm="join-example">.
      First the Cartesian product

      SUPPLIER &times; PART &times; SELLS

      is derived. Now only those tuples satisfying the
      conditions given in the WHERE clause are selected (i.e., the common
      named attributes have to be equal). Finally we project out all
      columns but S.SNAME and P.PNAME. 
     </para>

     <para>
     Another way to perform joins is to use the SQL JOIN syntax as follows:
<programlisting>
SELECT sname, pname from supplier
    JOIN sells USING (sno)
    JOIN part USING (pno);
</programlisting>
    giving again:
<screen>
 sname | pname
-------+-------
 Smith | Screw
 Adams | Screw
 Smith | Nut
 Blake | Nut
 Adams | Bolt
 Blake | Bolt
 Jones | Cam
 Blake | Cam
(8 rows) 
</screen>
     </para>

     <para>
     A joined table, created using JOIN syntax, is a table reference list
     item that occurs in a FROM clause and before any WHERE, GROUP BY,
     or HAVING clause.  Other table references, including table names or
     other JOIN clauses, can be included in the FROM clause if separated
     by commas.  JOINed tables are logically like any other
     table listed in the FROM clause.
     </para>

     <para>
      SQL JOINs come in two main types, CROSS JOINs (unqualified joins)
      and <firstterm>qualified JOINs</>.  Qualified joins can be further
      subdivided based on the way in which the <firstterm>join condition</>
      is specified (ON, USING, or NATURAL) and the way in which it is
      applied (INNER or OUTER join).
     </para>

    <variablelist>
        <title>Join Types</title>
        <varlistentry>
            <term>CROSS JOIN</term>
            <listitem>
            <cmdsynopsis>
                <arg choice="req"> <replaceable class="parameter">T1</replaceable> </arg>
                <command> CROSS JOIN </command>
                <arg choice="req"> <replaceable class="parameter">T2</replaceable> </arg>
            </cmdsynopsis>

            <para>
            A cross join takes two tables T1 and T2 having N and M rows
            respectively, and returns a joined table containing all
            N*M possible joined rows. For each row R1 of T1, each row
            R2 of T2 is joined with R1 to yield a joined table row JR
            consisting of all fields in R1 and R2. A CROSS JOIN is
            equivalent to an INNER JOIN ON TRUE.
            </para>
            </listitem>
        </varlistentry>

        <varlistentry>
            <term>Qualified JOINs</term>
            <listitem>

            <cmdsynopsis>
            <arg choice="req"> <replaceable class="parameter">T1</replaceable> </arg>
            <arg choice="opt"> NATURAL </arg>
            <group choice="opt">
                <arg choice="opt"> INNER </arg>
                <arg>
                <group choice="req">
                    <arg choice="plain"> LEFT </arg>
                    <arg choice="plain"> RIGHT </arg>
                    <arg choice="plain"> FULL </arg>
                </group>
                <arg choice="opt"> OUTER </arg>
                    </arg>
                </group>
            <command> JOIN </command>
            <arg choice="req"> <replaceable class="parameter">T2</replaceable> </arg>
            <group choice="req">
                <arg> ON <replaceable>search condition</replaceable></arg>
                <arg> USING ( <replaceable>join column list</replaceable> ) </arg>
            </group>
            </cmdsynopsis>

            <para>
            A qualified JOIN must specify its join condition
            by providing one (and only one) of NATURAL, ON, or
            USING.  The ON clause
            takes a <replaceable>search condition</replaceable>,
            which is the same as in a WHERE clause.  The USING
            clause takes a comma-separated list of column names,
            which the joined tables must have in common, and joins
            the tables on equality of those columns.  NATURAL is
            shorthand for a USING clause that lists all the common
            column names of the two tables.  A side-effect of both
            USING and NATURAL is that only one copy of each joined
            column is emitted into the result table (compare the
            relational-algebra definition of JOIN, shown earlier).
            </para>

            <!-- begin join semantics -->
            <variablelist>
            <varlistentry>
                <term>
                    <cmdsynopsis>
                        <arg> INNER </arg>
                        <command> JOIN </command>
                    </cmdsynopsis>
                </term>
                <listitem>
                <para>
                For each row R1 of T1, the joined table has a row for each row
                in T2 that satisfies the join condition with R1. 
                </para>
                <tip>
                <para>
                    The words INNER and OUTER are optional for all JOINs.
                    INNER is the default.  LEFT, RIGHT, and FULL imply an
                    OUTER JOIN.
                    </para>
                </tip>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>
                    <cmdsynopsis>
                        <arg choice="plain"> LEFT </arg>
                        <arg> OUTER </arg>
                        <command> JOIN </command>
                    </cmdsynopsis>
                </term>
                <listitem>
                <para>
                First, an INNER JOIN is performed.
                Then, for each row in T1 that does not satisfy the join
                condition with any row in T2, an additional joined row is
                returned with null fields in the columns from T2.
                </para>
                <tip>
                    <para>
                    The joined table unconditionally has a row for each row in T1.
                    </para>
                </tip>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>
                    <cmdsynopsis>
                        <arg choice="plain"> RIGHT </arg>
                        <arg> OUTER </arg>
                        <command> JOIN </command>
                    </cmdsynopsis>
                </term>
                <listitem>
                <para>
                First, an INNER JOIN is performed.
                Then, for each row in T2 that does not satisfy the join
                condition with any row in T1, an additional joined row is
                returned with null fields in the columns from T1.
                </para>
                <tip>
                    <para>
                    The joined table unconditionally has a row for each row in T2.
                    </para>
                </tip>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>
                    <cmdsynopsis>
                        <arg choice="plain"> FULL </arg>
                        <arg> OUTER </arg>
                        <command> JOIN </command>
                    </cmdsynopsis>
                </term>
                <listitem>
                <para>
                First, an INNER JOIN is performed.
                Then, for each row in T1 that does not satisfy the join
                condition with any row in T2, an additional joined row is
                returned with null fields in the columns from T2.
                Also, for each row in T2 that does not satisfy the join
                condition with any row in T1, an additional joined row is
                returned with null fields in the columns from T1.
                </para>
                <tip>
                    <para>
                    The joined table unconditionally has a row for every row of T1
                    and a row for every row of T2.
                    </para>
                </tip>
                </listitem>
            </varlistentry>
            </variablelist>
            <!-- end join semantics -->

            </listitem>
        </varlistentry>
     </variablelist>

     <para>
     JOINs of all types can be chained together or nested where either or both of
     <replaceable class="parameter">T1</replaceable> and
     <replaceable class="parameter">T2</replaceable> can be JOINed tables.
     Parenthesis can be used around JOIN clauses to control the order
     of JOINs which are otherwise processed left to right.
     </para>

    </sect3>

    <sect3>
     <title id="aggregates-tutorial">Aggregate Functions</title>

     <para>
      <acronym>SQL</acronym> provides aggregate functions such as AVG,
      COUNT, SUM, MIN, and MAX.  The argument(s) of an aggregate function
      are evaluated at each row that satisfies the WHERE
      clause, and the aggregate function is calculated over this set
      of input values.  Normally, an aggregate delivers a single
      result for a whole <command>SELECT</command> statement.  But if
      grouping is specified in the query, then a separate calculation
      is done over the rows of each group, and an aggregate result is
      delivered per group (see next section).

      <example>
       <title id="aggregates-example">Aggregates</title>

       <para>
        If we want to know the average cost of all parts in table PART we use
        the following query:

<programlisting>
SELECT AVG(PRICE) AS AVG_PRICE
    FROM PART;
</programlisting>
       </para>

       <para>
        The result is:

<screen>
 AVG_PRICE
-----------
   14.5
</screen>
       </para>

       <para>
        If we want to know how many parts are defined in table PART we use
        the statement:

<programlisting>
SELECT COUNT(PNO)
    FROM PART;
</programlisting>

        and get:

<screen>
 COUNT
-------
   4
</screen>

       </para>
      </example>
     </para>
    </sect3>

    <sect3>
     <title>Aggregation by Groups</title>

     <para>
      <acronym>SQL</acronym> allows one to partition the tuples of a table
      into groups. Then the
      aggregate functions described above can be applied to the groups &mdash;
      i.e., the value of the aggregate function is no longer calculated over
      all the values of the specified column but over all values of a
      group. Thus the aggregate function is evaluated separately for every
      group.
     </para>

     <para>
      The partitioning of the tuples into groups is done by using the
      keywords <command>GROUP BY</command> followed by a list of
      attributes that define the
      groups. If we have 
      <command>GROUP BY A<subscript>1</subscript>, &tdot;, A<subscript>k</subscript></command>
      we partition
      the relation into groups, such that two tuples are in the same group
      if and only if they agree on all the attributes 
      A<subscript>1</subscript>, &tdot;, A<subscript>k</subscript>.

      <example>
       <title id="aggregates-groupby">Aggregates</title>
       <para>
        If we want to know how many parts are sold by every supplier we
        formulate the query:

<programlisting>
SELECT S.SNO, S.SNAME, COUNT(SE.PNO)
    FROM SUPPLIER S, SELLS SE
    WHERE S.SNO = SE.SNO
    GROUP BY S.SNO, S.SNAME;
</programlisting>

        and get:

<screen>
 SNO | SNAME | COUNT
-----+-------+-------
  1  | Smith |   2
  2  | Jones |   1
  3  | Adams |   2
  4  | Blake |   3
</screen>
       </para>

       <para>
        Now let's have a look of what is happening here.
        First the join of the
        tables SUPPLIER and SELLS is derived:

<screen>
 S.SNO | S.SNAME | SE.PNO
-------+---------+--------
   1   |  Smith  |   1
   1   |  Smith  |   2
   2   |  Jones  |   4
   3   |  Adams  |   1
   3   |  Adams  |   3
   4   |  Blake  |   2
   4   |  Blake  |   3
   4   |  Blake  |   4
</screen>
       </para>

       <para>
        Next we partition the tuples into groups by putting all tuples
        together that agree on both attributes S.SNO and S.SNAME:

<screen>
 S.SNO | S.SNAME | SE.PNO
-------+---------+--------
   1   |  Smith  |   1
                 |   2
--------------------------
   2   |  Jones  |   4
--------------------------
   3   |  Adams  |   1
                 |   3
--------------------------
   4   |  Blake  |   2
                 |   3
                 |   4
</screen>
       </para>

       <para>
        In our example we got four groups and now we can apply the aggregate
        function COUNT to every group leading to the final result of the query
        given above.
       </para>
      </example>
     </para>

     <para>
      Note that for a query using GROUP BY and aggregate
      functions to make sense, the target list can only refer directly to
      the attributes being grouped by.  Other attributes can only be used
      inside the arguments of aggregate functions.  Otherwise there would
      not be a unique value to associate with the other attributes.
     </para>

     <para>
      Also observe that it makes no sense to ask for an aggregate of
      an aggregate, e.g., AVG(MAX(sno)), because a
      <command>SELECT</command> only does one pass of grouping and
      aggregation.  You can get a result of this kind by using a
      temporary table or a sub-SELECT in the FROM clause to do the
      first level of aggregation.
     </para>
    </sect3>

    <sect3>
     <title>Having</title>

     <para>
      The HAVING clause works much like the WHERE clause and is used to
      consider only those groups satisfying the qualification given in the
      HAVING clause.  Essentially, WHERE filters out unwanted input rows
      before grouping and aggregation are done, whereas HAVING filters out
      unwanted group rows post-GROUP.  Therefore, WHERE cannot refer to the
      results of aggregate functions.  On the other hand, there's no point
      in writing a HAVING condition that doesn't involve an aggregate
      function!  If your condition doesn't involve aggregates, you might
      as well write it in WHERE, and thereby avoid the computation of
      aggregates for groups that you're just going to throw away anyway.

      <example>
       <title id="having-example">Having</title>

       <para>
        If we want only those suppliers selling more than one part we use the
        query:

<programlisting>
SELECT S.SNO, S.SNAME, COUNT(SE.PNO)
    FROM SUPPLIER S, SELLS SE
    WHERE S.SNO = SE.SNO
    GROUP BY S.SNO, S.SNAME
    HAVING COUNT(SE.PNO) &gt; 1;
</programlisting>

        and get:

<screen>
 SNO | SNAME | COUNT
-----+-------+-------
  1  | Smith |   2
  3  | Adams |   2
  4  | Blake |   3
</screen>
       </para>
      </example>
     </para>
    </sect3>

    <sect3>
     <title>Subqueries</title>

     <para>
      In the WHERE and HAVING clauses the use of subqueries (subselects) is
      allowed in every place where a value is expected. In this case the
      value must be derived by evaluating the subquery first. The usage of
      subqueries extends the expressive power of
      <acronym>SQL</acronym>.

      <example>
       <title id="subselect-example">Subselect</title>

       <para>
        If we want to know all parts having a greater price than the part
        named 'Screw' we use the query:

<programlisting>
SELECT * 
    FROM PART 
    WHERE PRICE &gt; (SELECT PRICE FROM PART
                   WHERE PNAME='Screw');
</programlisting>
       </para>

       <para>
        The result is:

<screen>
 PNO |  PNAME  |  PRICE
-----+---------+--------
  3  |  Bolt   |   15
  4  |  Cam    |   25
</screen>
       </para>

       <para>
        When we look at the above query we can see the keyword
        <command>SELECT</command> two times. The first one at the
        beginning of the query - we will refer to it as outer
        <command>SELECT</command> - and the one in the WHERE clause which
        begins a nested query - we will refer to it as inner
        <command>SELECT</command>. For every tuple of the outer
        <command>SELECT</command> the inner <command>SELECT</command> has
        to be evaluated. After every evaluation we know the price of the
        tuple named 'Screw' and we can check if the price of the actual
        tuple is greater.  (Actually, in this example the inner query need
        only be evaluated once, since it does not depend on the state of
        the outer query.)
       </para>

       <para>
        If we want to know all suppliers that do not sell any part 
        (e.g., to be able to remove these suppliers from the database) we use:

<programlisting>
SELECT * 
    FROM SUPPLIER S
    WHERE NOT EXISTS
        (SELECT * FROM SELLS SE
         WHERE SE.SNO = S.SNO);
</programlisting>
       </para>

       <para>
        In our example the result will be empty because every supplier
        sells at least one part. Note that we use S.SNO from the outer
        <command>SELECT</command> within the WHERE clause of the inner
        <command>SELECT</command>. Here the subquery must be evaluated
        afresh for each tuple from the outer query, i.e., the value for
        S.SNO is always taken from the current tuple of the outer
        <command>SELECT</command>.
       </para>
      </example>
     </para>
    </sect3>

    <sect3>
     <title>Subqueries in FROM</title>

     <para>
      A somewhat different way of using subqueries is to put them in the
      FROM clause.  This is a useful feature because a subquery of this
      kind can output multiple columns and rows, whereas a subquery used
      in an expression must deliver just a single result.  It also lets
      us get more than one round of grouping/aggregation without resorting
      to a temporary table.

      <example>
       <title id="subselect-in-from-example">Subselect in FROM</title>

       <para>
        If we want to know the highest average part price among all our
        suppliers, we cannot write MAX(AVG(PRICE)), but we can write:

<programlisting>
SELECT MAX(subtable.avgprice)
    FROM (SELECT AVG(P.PRICE) AS avgprice
          FROM SUPPLIER S, PART P, SELLS SE
          WHERE S.SNO = SE.SNO AND
                P.PNO = SE.PNO
          GROUP BY S.SNO) subtable;
</programlisting>

        The subquery returns one row per supplier (because of its GROUP BY)
        and then we aggregate over those rows in the outer query.
       </para>
      </example>
     </para>
    </sect3>

    <sect3>
     <title>Union, Intersect, Except</title>

     <para>
      These operations calculate the union, intersection and set theoretic
      difference of the tuples derived by two subqueries.

      <example>
       <title id="union-example">Union, Intersect, Except</title>

       <para>
        The following query is an example for UNION:

<programlisting>
SELECT S.SNO, S.SNAME, S.CITY
    FROM SUPPLIER S
    WHERE S.SNAME = 'Jones'
UNION
    SELECT S.SNO, S.SNAME, S.CITY
    FROM SUPPLIER S
    WHERE S.SNAME = 'Adams';    
</programlisting>

gives the result:

<screen>
 SNO | SNAME |  CITY
-----+-------+--------
  2  | Jones | Paris
  3  | Adams | Vienna
</screen>
       </para>

       <para>
        Here is an example for INTERSECT:

<programlisting>
SELECT S.SNO, S.SNAME, S.CITY
    FROM SUPPLIER S
    WHERE S.SNO &gt; 1
INTERSECT
    SELECT S.SNO, S.SNAME, S.CITY
    FROM SUPPLIER S
    WHERE S.SNO &lt; 3;
</programlisting>

        gives the result:

<screen>
 SNO | SNAME |  CITY
-----+-------+--------
  2  | Jones | Paris
</screen>

        The only tuple returned by both parts of the query is the one having SNO=2.
       </para>

       <para>
        Finally an example for EXCEPT:

<programlisting>
SELECT S.SNO, S.SNAME, S.CITY
    FROM SUPPLIER S
    WHERE S.SNO &gt; 1
EXCEPT
    SELECT S.SNO, S.SNAME, S.CITY
    FROM SUPPLIER S
    WHERE S.SNO &gt; 3;
</programlisting>

        gives the result:

<screen>
 SNO | SNAME |  CITY
-----+-------+--------
  2  | Jones | Paris
  3  | Adams | Vienna
</screen>
       </para>
      </example>
     </para>
    </sect3>
   </sect2>

   <sect2 id="datadef">
    <title>Data Definition</title>

    <para>
     There is a set of commands used for data definition included in the
     <acronym>SQL</acronym> language. 
    </para>

    <sect3 id="create">
     <title id="create-title">Create Table</title>

     <para>
      The most fundamental command for data definition is the
      one that creates a new relation (a new table). The syntax of the
      <command>CREATE TABLE</command> command is:

<synopsis>
CREATE TABLE <replaceable class="parameter">table_name</replaceable>
    (<replaceable class="parameter">name_of_attr_1</replaceable> <replaceable class="parameter">type_of_attr_1</replaceable>
     [, <replaceable class="parameter">name_of_attr_2</replaceable> <replaceable class="parameter">type_of_attr_2</replaceable> 
     [, ...]]);
</synopsis>

      <example>
       <title id="table-create">Table Creation</title>

       <para>
        To create the tables defined in
        <xref linkend="supplier-fig" endterm="supplier-fig"> the
        following <acronym>SQL</acronym> statements are used:

<programlisting>
CREATE TABLE SUPPLIER
    (SNO   INTEGER,
     SNAME VARCHAR(20),
     CITY  VARCHAR(20));
</programlisting>

<programlisting>
CREATE TABLE PART
    (PNO   INTEGER,
     PNAME VARCHAR(20),
     PRICE DECIMAL(4 , 2));
</programlisting>

<programlisting>
CREATE TABLE SELLS
    (SNO INTEGER,
     PNO INTEGER);
</programlisting>
       </para>
      </example>
     </para>
    </sect3>

    <sect3>
     <title>Data Types in <acronym>SQL</acronym></title>

     <para>
      The following is a list of some data types that are supported by 
      <acronym>SQL</acronym>:

      <itemizedlist>
       <listitem>
        <para>
         INTEGER: signed fullword binary integer (31 bits precision).
        </para>
       </listitem>

       <listitem>
        <para>
         SMALLINT: signed halfword binary integer (15 bits precision).
        </para>
       </listitem>

       <listitem>
        <para>
         DECIMAL (<replaceable class="parameter">p</replaceable>[,<replaceable class="parameter">q</replaceable>]):
         signed packed decimal number of up to
         <replaceable class="parameter">p</replaceable>
         digits, with
         <replaceable class="parameter">q</replaceable>
         digits to the right of the decimal point.
         If <replaceable class="parameter">q</replaceable>
         is omitted it is assumed to be 0.
        </para>
       </listitem>

       <listitem>
        <para>
         FLOAT: signed doubleword floating point number.
        </para>
       </listitem>

       <listitem>
        <para>
         VARCHAR(<replaceable class="parameter">n</replaceable>):
         varying length character string of maximum length
         <replaceable class="parameter">n</replaceable>.
        </para>
       </listitem>

       <listitem>
        <para>
         CHAR(<replaceable class="parameter">n</replaceable>):
         fixed length character string of length
         <replaceable class="parameter">n</replaceable>.
        </para>
       </listitem>

      </itemizedlist>
     </para>
    </sect3>

    <sect3>
     <title>Create Index</title>

     <para>
      Indexes are used to speed up access to a relation. If a relation <classname>R</classname>
      has an index on attribute <classname>A</classname> then we can
      retrieve all tuples <replaceable>t</replaceable>
      having
      <replaceable>t</replaceable>(<classname>A</classname>) = <replaceable>a</replaceable>
      in time roughly proportional to the number of such
      tuples <replaceable>t</replaceable>
      rather than in time proportional to the size of <classname>R</classname>.
     </para>

     <para>
      To create an index in <acronym>SQL</acronym>
      the <command>CREATE INDEX</command> command is used. The syntax is:

<programlisting>
CREATE INDEX <replaceable class="parameter">index_name</replaceable> 
    ON <replaceable class="parameter">table_name</replaceable> ( <replaceable class="parameter">name_of_attribute</replaceable> );
</programlisting>
     </para>

     <para>
      <example>
       <title id="index-create">Create Index</title>

       <para>
        To create an index named I on attribute SNAME of relation SUPPLIER
        we use the following statement:

<programlisting>
CREATE INDEX I ON SUPPLIER (SNAME);
</programlisting>
     </para>

       <para>
        The created index is maintained automatically, i.e., whenever a new
        tuple is inserted into the relation SUPPLIER the index I is
        adapted. Note that the only changes a user can perceive when an
        index is present are increased speed for <command>SELECT</command>
        and decreases in speed of updates.
       </para>
      </example>
     </para>
    </sect3>

    <sect3>
     <title>Create View</title>

     <para>
      A view can be regarded as a <firstterm>virtual table</firstterm>,
      i.e., a table that
      does not <emphasis>physically</emphasis> exist in the database
      but looks to the user
      as if it does. By contrast, when we talk of a
      <firstterm>base table</firstterm> there is
      really a physically stored counterpart of each row of the table
      somewhere in the physical storage.
     </para>

     <para>
      Views do not have their own, physically separate, distinguishable
      stored data. Instead, the system stores the definition of the
      view (i.e., the rules about how to access physically stored base
      tables in order to materialize the view) somewhere in the system
      catalogs (see
      <xref linkend="tutorial-catalogs-title" endterm="tutorial-catalogs-title">). For a
      discussion on different techniques to implement views refer to
<!--
      section
      <xref linkend="view-impl" endterm="view-impl">.
-->
      <citetitle>SIM98</citetitle>.
     </para>

     <para>
      In <acronym>SQL</acronym> the <command>CREATE VIEW</command>
      command is used to define a view. The syntax
      is:

<programlisting>
CREATE VIEW <replaceable class="parameter">view_name</replaceable>
    AS <replaceable class="parameter">select_stmt</replaceable>
</programlisting>

      where <replaceable class="parameter">select_stmt</replaceable> 
      is a valid select statement as defined
      in <xref linkend="select-title" endterm="select-title">.
      Note that <replaceable class="parameter">select_stmt</replaceable> is
      not executed when the view is created. It is just stored in the 
      <firstterm>system catalogs</firstterm>
      and is executed whenever a query against the view is made.
     </para>

     <para>
      Let the following view definition be given (we use
      the tables from
      <xref linkend="supplier-fig" endterm="supplier-fig"> again):

<programlisting>
CREATE VIEW London_Suppliers
    AS SELECT S.SNAME, P.PNAME
        FROM SUPPLIER S, PART P, SELLS SE
        WHERE S.SNO = SE.SNO AND
              P.PNO = SE.PNO AND
              S.CITY = 'London';
</programlisting>
     </para>

     <para>
      Now we can use this <firstterm>virtual relation</firstterm>
      <classname>London_Suppliers</classname> as
      if it were another base table:

<programlisting>
SELECT * FROM London_Suppliers
    WHERE PNAME = 'Screw';
</programlisting>

      which will return the following table:

<screen>
 SNAME | PNAME
-------+-------
 Smith | Screw                 
</screen>
     </para>

     <para>
      To calculate this result the database system has to do a
      <emphasis>hidden</emphasis>
      access to the base tables SUPPLIER, SELLS and PART first. It
      does so by executing the query given in the view definition against
      those base tables. After that the additional qualifications
      (given in the
      query against the view) can be applied to obtain the resulting
      table.
     </para>
    </sect3>

    <sect3>
     <title>Drop Table, Drop Index, Drop View</title>

     <para>
      To destroy a table (including all tuples stored in that table) the
      <command>DROP TABLE</command> command is used:

<programlisting>
DROP TABLE <replaceable class="parameter">table_name</replaceable>;
</programlisting>
      </para>

     <para>
      To destroy the SUPPLIER table use the following statement:

<programlisting>
DROP TABLE SUPPLIER;
</programlisting>
     </para>

     <para>
      The <command>DROP INDEX</command> command is used to destroy an index:

<programlisting>
DROP INDEX <replaceable class="parameter">index_name</replaceable>;
</programlisting>
     </para>

     <para>
      Finally to destroy a given view use the command <command>DROP
      VIEW</command>:

<programlisting>
DROP VIEW <replaceable class="parameter">view_name</replaceable>;
</programlisting>
     </para>
    </sect3>
   </sect2>

   <sect2>
    <title>Data Manipulation</title>

    <sect3>
     <title>Insert Into</title>

     <para>
      Once a table is created (see
      <xref linkend="create-title" endterm="create-title">), it can be filled
      with tuples using the command <command>INSERT INTO</command>.
      The syntax is:

<programlisting>
INSERT INTO <replaceable class="parameter">table_name</replaceable> (<replaceable class="parameter">name_of_attr_1</replaceable> 
    [, <replaceable class="parameter">name_of_attr_2</replaceable> [,...]])
    VALUES (<replaceable class="parameter">val_attr_1</replaceable> [, <replaceable class="parameter">val_attr_2</replaceable> [, ...]]);
</programlisting>
     </para>

     <para>
      To insert the first tuple into the relation SUPPLIER (from
      <xref linkend="supplier-fig" endterm="supplier-fig">) we use the
      following statement:

<programlisting>
INSERT INTO SUPPLIER (SNO, SNAME, CITY)
    VALUES (1, 'Smith', 'London');
</programlisting>
     </para>

     <para>
      To insert the first tuple into the relation SELLS we use:

<programlisting>
INSERT INTO SELLS (SNO, PNO)
    VALUES (1, 1);
</programlisting>
     </para>
    </sect3>

    <sect3>
     <title>Update</title>

     <para>
      To change one or more attribute values of tuples in a relation the
      <command>UPDATE</command> command is used. The syntax is:

<programlisting>
UPDATE <replaceable class="parameter">table_name</replaceable>
    SET <replaceable class="parameter">name_of_attr_1</replaceable> = <replaceable class="parameter">value_1</replaceable> 
        [, ... [, <replaceable class="parameter">name_of_attr_k</replaceable> = <replaceable class="parameter">value_k</replaceable>]]
    WHERE <replaceable class="parameter">condition</replaceable>;
</programlisting>
     </para>

     <para>
      To change the value of attribute PRICE of the part 'Screw' in the
      relation PART we use:

<programlisting>
UPDATE PART
    SET PRICE = 15
    WHERE PNAME = 'Screw';
</programlisting>
     </para>

     <para>
      The new value of attribute PRICE of the tuple whose name is 'Screw' is
      now 15.
     </para>
    </sect3>

    <sect3>
     <title>Delete</title>

     <para>
      To delete a tuple from a particular table use the command DELETE
      FROM. The syntax is:

<programlisting>
DELETE FROM <replaceable class="parameter">table_name</replaceable>
    WHERE <replaceable class="parameter">condition</replaceable>;
</programlisting>
     </para>

     <para>
      To delete the supplier called 'Smith' of the table SUPPLIER the
      following statement is used:

<programlisting>
DELETE FROM SUPPLIER
    WHERE SNAME = 'Smith';
</programlisting>
     </para>
    </sect3>
   </sect2>

   <sect2 id="tutorial-catalogs">
    <title id="tutorial-catalogs-title">System Catalogs</title>

    <para>
     In every <acronym>SQL</acronym> database system
     <firstterm>system catalogs</firstterm> are used to keep
     track of which tables, views indexes etc. are defined in the
     database. These system catalogs can be queried as if they were normal
     relations. For example there is one catalog used for the definition of
     views. This catalog stores the query from the view definition. Whenever
     a query against a view is made, the system first gets the
     <firstterm>view definition query</firstterm> out of the catalog
     and materializes the view
     before proceeding with the user query (see
<!--
      section
      <xref linkend="view-impl" endterm="view-impl">.
    <citetitle>SIM98</citetitle>
-->
     <xref linkend="SIM98" endterm="SIM98">
     for a more detailed
     description). For more information about system catalogs refer to
     <xref linkend="DATE04" endterm="DATE04">.
    </para>
   </sect2>

   <sect2>
    <title>Embedded <acronym>SQL</acronym></title>

    <para>
     In this section we will sketch how <acronym>SQL</acronym> can be
     embedded into a host language (e.g., <literal>C</literal>).
     There are two main reasons why we want to use <acronym>SQL</acronym>
     from a host language:

     <itemizedlist>
      <listitem>
       <para>
        There are queries that cannot be formulated using pure <acronym>SQL</acronym>
        (i.e., recursive queries). To be able to perform such queries we need a
        host language with a greater expressive power than
        <acronym>SQL</acronym>.
       </para>
      </listitem>

      <listitem>
       <para>
        We simply want to access a database from some application that
        is written in the host language (e.g., a ticket reservation system
        with a graphical user interface is written in C and the information
        about which tickets are still left is stored in a database that can be
        accessed using embedded <acronym>SQL</acronym>).
       </para>
      </listitem>
     </itemizedlist>
    </para>

    <para>
     A program using embedded <acronym>SQL</acronym>
     in a host language consists of statements
     of the host language and of
     <firstterm>embedded <acronym>SQL</acronym></firstterm>
     (<acronym>ESQL</acronym>) statements. Every <acronym>ESQL</acronym>
     statement begins with the keywords <command>EXEC SQL</command>.
     The <acronym>ESQL</acronym> statements are
     transformed to statements of the host language
     by a <firstterm>precompiler</firstterm>
     (which usually inserts
     calls to library routines that perform the various <acronym>SQL</acronym>
     commands). 
    </para>

    <para>
     When we look at the examples throughout
     <xref linkend="select-title" endterm="select-title"> we
     realize that the result of the queries is very often a set of
     tuples. Most host languages are not designed to operate on sets so we
     need a mechanism to access every single tuple of the set of tuples
     returned by a SELECT statement. This mechanism can be provided by
     declaring a <firstterm>cursor</firstterm>.
     After that we can use the <command>FETCH</command> command to
     retrieve a tuple and set the cursor to the next tuple.
    </para>

    <para>
     For a detailed discussion on embedded <acronym>SQL</acronym>
     refer to
     <xref linkend="DATE97" endterm="DATE97">,
     <xref linkend="DATE04" endterm="DATE04">,
     or
     <xref linkend="ULL88" endterm="ULL88">.
    </para>
   </sect2>
  </sect1>
 </chapter>
@


1.48
log
@Proofreading adjustments for first two parts of documentation (Tutorial
and SQL).
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.47 2008/02/15 22:17:06 tgl Exp $ -->
d154 1
a154 1
     <programlisting>
d171 1
a171 1
     </programlisting>
d533 1
a533 1
         <programlisting>
d540 1
a540 1
         </programlisting>
d549 1
a549 1
        <programlisting>
d559 1
a559 1
        </programlisting>
d567 1
a567 1
        <programlisting>
d572 1
a572 1
        </programlisting>
d582 1
a582 1
        <programlisting>
d587 1
a587 1
        </programlisting>
d599 1
a599 1
        <programlisting>
d601 1
a601 1
        </programlisting>
d618 1
a618 1
        <programlisting>
d628 1
a628 1
        </programlisting>
d633 1
a633 1
        <programlisting>
d638 1
a638 1
        </programlisting>
d662 1
a662 1
      <programlisting>
d664 1
a664 1
      </programlisting>
d673 1
a673 1
      <programlisting>
d678 1
a678 1
      </programlisting>
d727 1
a727 1
     <programlisting>
d729 1
a729 1
     </programlisting>
d742 1
a742 1
     <programlisting>
d747 1
a747 1
     </programlisting>
d816 1
a816 1
       <programlisting>
d818 1
a818 1
       </programlisting>
d854 1
a854 1
     <synopsis>
d867 1
a867 1
     </synopsis>
d889 1
a889 1
        <programlisting>
d892 1
a892 1
        </programlisting>
d896 1
a896 1
        <programlisting>
d901 1
a901 1
        </programlisting>
d910 1
a910 1
        <programlisting>
d914 1
a914 1
        </programlisting>
d918 1
a918 1
        <programlisting>
d923 1
a923 1
        </programlisting>
d935 1
a935 1
        <programlisting>
d940 1
a940 1
        </programlisting>
d944 1
a944 1
        <programlisting>
d948 1
a948 1
        </programlisting>
d956 1
a956 1
        <programlisting>
d960 1
a960 1
        </programlisting>
d964 1
a964 1
        <programlisting>
d970 1
a970 1
        </programlisting>
d995 1
a995 1
      <programlisting>
d1000 1
a1000 1
      </programlisting>
d1004 1
a1004 1
      <programlisting>
d1015 1
a1015 1
      </programlisting>
d1037 2
a1038 2
     <programlisting>
select sname, pname from supplier
d1041 1
a1041 1
    </programlisting>
d1043 1
a1043 1
    <programlisting>
d1055 1
a1055 1
     </programlisting>
d1270 1
a1270 1
        <programlisting>
d1273 1
a1273 1
        </programlisting>
d1279 1
a1279 1
        <programlisting>
d1283 1
a1283 1
        </programlisting>
d1290 1
a1290 1
        <programlisting>
d1293 1
a1293 1
        </programlisting>
d1297 1
a1297 1
        <programlisting>
d1301 1
a1301 1
        </programlisting>
d1338 1
a1338 1
        <programlisting>
d1343 1
a1343 1
        </programlisting>
d1347 1
a1347 1
        <programlisting>
d1354 1
a1354 1
        </programlisting>
d1362 1
a1362 1
        <programlisting>
d1373 1
a1373 1
        </programlisting>
d1380 1
a1380 1
        <programlisting>
d1394 1
a1394 1
        </programlisting>
d1445 1
a1445 1
        <programlisting>
d1451 1
a1451 1
        </programlisting>
d1455 1
a1455 1
        <programlisting>
d1461 1
a1461 1
        </programlisting>
d1484 1
a1484 1
        <programlisting>
d1489 1
a1489 1
        </programlisting>
d1495 1
a1495 1
        <programlisting>
d1500 1
a1500 1
        </programlisting>
d1522 1
a1522 1
        <programlisting>
d1528 1
a1528 1
        </programlisting>
d1562 1
a1562 1
        <programlisting>
d1569 1
a1569 1
        </programlisting>
d1591 1
a1591 1
        <programlisting>
d1599 1
a1599 1
        </programlisting>
d1603 1
a1603 1
        <programlisting>
d1608 1
a1608 1
        </programlisting>
d1614 1
a1614 1
        <programlisting>
d1622 1
a1622 1
        </programlisting>
d1626 1
a1626 1
        <programlisting>
d1630 1
a1630 1
        </programlisting>
d1638 1
a1638 1
        <programlisting>
d1646 1
a1646 1
        </programlisting>
d1650 1
a1650 1
        <programlisting>
d1655 1
a1655 1
        </programlisting>
d1678 1
a1678 1
      <synopsis>
d1683 1
a1683 1
      </synopsis>
d1693 1
a1693 1
        <programlisting>
d1698 1
a1698 1
     </programlisting>
d1700 1
a1700 1
     <programlisting>
d1705 1
a1705 1
     </programlisting>
d1707 1
a1707 1
     <programlisting>
d1711 1
a1711 1
        </programlisting>
d1794 1
a1794 1
      <programlisting>
d1797 1
a1797 1
      </programlisting>
d1808 1
a1808 1
      <programlisting>
d1810 1
a1810 1
      </programlisting>
d1858 1
a1858 1
      <programlisting>
d1861 1
a1861 1
      </programlisting>
d1877 1
a1877 1
      <programlisting>
d1884 1
a1884 1
      </programlisting>
d1892 1
a1892 1
      <programlisting>
d1895 1
a1895 1
      </programlisting>
d1899 1
a1899 1
      <programlisting>
d1903 1
a1903 1
      </programlisting>
d1925 1
a1925 1
      <programlisting>
d1927 1
a1927 1
       </programlisting>
d1933 1
a1933 1
      <programlisting>
d1935 1
a1935 1
      </programlisting>
d1941 1
a1941 1
      <programlisting>
d1943 1
a1943 1
      </programlisting>
d1950 1
a1950 1
      <programlisting>
d1952 1
a1952 1
      </programlisting>
d1969 1
a1969 1
      <programlisting>
d1973 1
a1973 1
      </programlisting>
d1981 1
a1981 1
      <programlisting>
d1984 1
a1984 1
      </programlisting>
d1990 1
a1990 1
      <programlisting>
d1993 1
a1993 1
      </programlisting>
d2004 1
a2004 1
      <programlisting>
d2009 1
a2009 1
      </programlisting>
d2016 1
a2016 1
      <programlisting>
d2020 1
a2020 1
      </programlisting>
d2036 1
a2036 1
      <programlisting>
d2039 1
a2039 1
      </programlisting>
d2046 1
a2046 1
      <programlisting>
d2049 1
a2049 1
      </programlisting>
@


1.48.14.1
log
@Fix indentation of verbatim block elements

Block elements with verbatim formatting (literallayout, programlisting,
screen, synopsis) should be aligned at column 0 independent of the surrounding
SGML, because whitespace is significant, and indenting them creates erratic
whitespace in the output.  The CSS stylesheets already take care of indenting
the output.

Assorted markup improvements to go along with it.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.48 2009/04/27 16:27:36 momjian Exp $ -->
d154 1
a154 1
<screen>
d171 1
a171 1
</screen>
d533 1
a533 1
<screen>
d540 1
a540 1
</screen>
d549 1
a549 1
<screen>
d559 1
a559 1
</screen>
d567 1
a567 1
<screen>
d572 1
a572 1
</screen>
d582 1
a582 1
<screen>
d587 1
a587 1
</screen>
d599 1
a599 1
<programlisting>
d601 1
a601 1
</programlisting>
d618 1
a618 1
<screen>
d628 1
a628 1
</screen>
d633 1
a633 1
<screen>
d638 1
a638 1
</screen>
d662 1
a662 1
<programlisting>
d664 1
a664 1
</programlisting>
d673 1
a673 1
<screen>
d678 1
a678 1
</screen>
d727 1
a727 1
<programlisting>
d729 1
a729 1
</programlisting>
d742 1
a742 1
<programlisting>
d747 1
a747 1
</programlisting>
d816 1
a816 1
<programlisting>
d818 1
a818 1
</programlisting>
d854 1
a854 1
<synopsis>
d867 1
a867 1
</synopsis>
d889 1
a889 1
<programlisting>
d892 1
a892 1
</programlisting>
d896 1
a896 1
<screen>
d901 1
a901 1
</screen>
d910 1
a910 1
<programlisting>
d914 1
a914 1
</programlisting>
d918 1
a918 1
<screen>
d923 1
a923 1
</screen>
d935 1
a935 1
<programlisting>
d940 1
a940 1
</programlisting>
d944 1
a944 1
<screen>
d948 1
a948 1
</screen>
d956 1
a956 1
<programlisting>
d960 1
a960 1
</programlisting>
d964 1
a964 1
<screen>
d970 1
a970 1
</screen>
d995 1
a995 1
<programlisting>
d1000 1
a1000 1
</programlisting>
d1004 1
a1004 1
<screen>
d1015 1
a1015 1
</screen>
d1037 2
a1038 2
<programlisting>
SELECT sname, pname from supplier
d1041 1
a1041 1
</programlisting>
d1043 1
a1043 1
<screen>
d1055 1
a1055 1
</screen>
d1270 1
a1270 1
<programlisting>
d1273 1
a1273 1
</programlisting>
d1279 1
a1279 1
<screen>
d1283 1
a1283 1
</screen>
d1290 1
a1290 1
<programlisting>
d1293 1
a1293 1
</programlisting>
d1297 1
a1297 1
<screen>
d1301 1
a1301 1
</screen>
d1338 1
a1338 1
<programlisting>
d1343 1
a1343 1
</programlisting>
d1347 1
a1347 1
<screen>
d1354 1
a1354 1
</screen>
d1362 1
a1362 1
<screen>
d1373 1
a1373 1
</screen>
d1380 1
a1380 1
<screen>
d1394 1
a1394 1
</screen>
d1445 1
a1445 1
<programlisting>
d1451 1
a1451 1
</programlisting>
d1455 1
a1455 1
<screen>
d1461 1
a1461 1
</screen>
d1484 1
a1484 1
<programlisting>
d1489 1
a1489 1
</programlisting>
d1495 1
a1495 1
<screen>
d1500 1
a1500 1
</screen>
d1522 1
a1522 1
<programlisting>
d1528 1
a1528 1
</programlisting>
d1562 1
a1562 1
<programlisting>
d1569 1
a1569 1
</programlisting>
d1591 1
a1591 1
<programlisting>
d1599 1
a1599 1
</programlisting>
d1603 1
a1603 1
<screen>
d1608 1
a1608 1
</screen>
d1614 1
a1614 1
<programlisting>
d1622 1
a1622 1
</programlisting>
d1626 1
a1626 1
<screen>
d1630 1
a1630 1
</screen>
d1638 1
a1638 1
<programlisting>
d1646 1
a1646 1
</programlisting>
d1650 1
a1650 1
<screen>
d1655 1
a1655 1
</screen>
d1678 1
a1678 1
<synopsis>
d1683 1
a1683 1
</synopsis>
d1693 1
a1693 1
<programlisting>
d1698 1
a1698 1
</programlisting>
d1700 1
a1700 1
<programlisting>
d1705 1
a1705 1
</programlisting>
d1707 1
a1707 1
<programlisting>
d1711 1
a1711 1
</programlisting>
d1794 1
a1794 1
<programlisting>
d1797 1
a1797 1
</programlisting>
d1808 1
a1808 1
<programlisting>
d1810 1
a1810 1
</programlisting>
d1858 1
a1858 1
<programlisting>
d1861 1
a1861 1
</programlisting>
d1877 1
a1877 1
<programlisting>
d1884 1
a1884 1
</programlisting>
d1892 1
a1892 1
<programlisting>
d1895 1
a1895 1
</programlisting>
d1899 1
a1899 1
<screen>
d1903 1
a1903 1
</screen>
d1925 1
a1925 1
<programlisting>
d1927 1
a1927 1
</programlisting>
d1933 1
a1933 1
<programlisting>
d1935 1
a1935 1
</programlisting>
d1941 1
a1941 1
<programlisting>
d1943 1
a1943 1
</programlisting>
d1950 1
a1950 1
<programlisting>
d1952 1
a1952 1
</programlisting>
d1969 1
a1969 1
<programlisting>
d1973 1
a1973 1
</programlisting>
d1981 1
a1981 1
<programlisting>
d1984 1
a1984 1
</programlisting>
d1990 1
a1990 1
<programlisting>
d1993 1
a1993 1
</programlisting>
d2004 1
a2004 1
<programlisting>
d2009 1
a2009 1
</programlisting>
d2016 1
a2016 1
<programlisting>
d2020 1
a2020 1
</programlisting>
d2036 1
a2036 1
<programlisting>
d2039 1
a2039 1
</programlisting>
d2046 1
a2046 1
<programlisting>
d2049 1
a2049 1
</programlisting>
@


1.47
log
@Allow AS to be omitted when specifying an output column name in SELECT
(or RETURNING), but only when the output name is not any SQL keyword.
This seems as close as we can get to the standard's syntax without a
great deal of thrashing.  Original patch by Hiroshi Saito, amended by me.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.46 2007/02/16 03:50:29 momjian Exp $ -->
d98 1
a98 1
   language, i.e. all computable queries (e.g. recursive queries) will be
d764 1
a764 1
     <firstterm>expressive power</firstterm>; i.e. all queries that
d814 1
a814 1
       arithmetic operations as well as comparisons, e.g.
d1030 1
a1030 1
      conditions given in the WHERE clause are selected (i.e. the common
d1315 1
a1315 1
      i.e. the value of the aggregate function is no longer calculated over
d1520 1
a1520 1
        (e.g. to be able to remove these suppliers from the database) we use:
d1536 1
a1536 1
        afresh for each tuple from the outer query, i.e. the value for
d1814 1
a1814 1
        The created index is maintained automatically, i.e. whenever a new
d1829 1
a1829 1
      i.e. a table that
d1841 1
a1841 1
      view (i.e. the rules about how to access physically stored base
d2085 1
a2085 1
     embedded into a host language (e.g. <literal>C</literal>).
d2093 1
a2093 1
        (i.e. recursive queries). To be able to perform such queries we need a
d2102 1
a2102 1
        is written in the host language (e.g. a ticket reservation system
@


1.46
log
@Remove tabs from SGML files to help tag alingment and improve
detection of tabs are added in the future.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.45 2007/02/01 19:10:24 momjian Exp $ -->
d856 1
a856 1
    * | <replaceable class="PARAMETER">expression</replaceable> [ AS <replaceable class="PARAMETER">output_name</replaceable> ] [, ...]
@


1.45
log
@Wording cleanup for error messages.  Also change can't -> cannot.

Standard English uses "may", "can", and "might" in different ways:

        may - permission, "You may borrow my rake."

        can - ability, "I can lift that log."

        might - possibility, "It might rain today."

Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice.  Similarly, "It may crash" is better stated, "It might crash".
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.44 2007/01/31 20:56:19 momjian Exp $ -->
d417 5
a421 5
	SELECT (&sigma;): extracts <firstterm>tuples</firstterm> from
	a relation that
	satisfy a given restriction. Let <parameter>R</parameter> be a 
	table that contains an attribute
	<parameter>A</parameter>.
d423 4
a426 4
	where <literal>t</literal> denotes a
	tuple of <parameter>R</parameter> and <literal>t(A)</literal>
	denotes the value of attribute <parameter>A</parameter> of
	tuple <literal>t</literal>.
d432 7
a438 7
	PROJECT (&pi;): extracts specified
	<firstterm>attributes</firstterm> (columns) from a
	relation. Let <classname>R</classname> be a relation
	that contains an attribute <classname>X</classname>.
	&pi;<subscript>X</subscript>(<classname>R</classname>) = {t(X) &mid; t &isin; <classname>R</classname>},
	where <literal>t</literal>(<classname>X</classname>) denotes the value of
	attribute <classname>X</classname> of tuple <literal>t</literal>.
d444 13
a456 13
	PRODUCT (&times;): builds the Cartesian product of two
	relations. Let <classname>R</classname> be a table with arity
	<literal>k</literal><subscript>1</subscript> and let
	<classname>S</classname> be a table with
	arity <literal>k</literal><subscript>2</subscript>.
	<classname>R</classname> &times; <classname>S</classname>
	is the set of all 
	<literal>k</literal><subscript>1</subscript>
	+ <literal>k</literal><subscript>2</subscript>-tuples
	whose first <literal>k</literal><subscript>1</subscript>
	components form a tuple in <classname>R</classname> and whose last
	<literal>k</literal><subscript>2</subscript> components form a
	tuple in <classname>S</classname>.
d462 6
a467 6
	UNION (&cup;): builds the set-theoretic union of two
	tables. Given the tables <classname>R</classname> and
	<classname>S</classname> (both must have the same arity),
	the union <classname>R</classname> &cup; <classname>S</classname>
	is the set of tuples that are in <classname>R</classname>
	or <classname>S</classname> or both.
d473 10
a482 10
	INTERSECT (&cap;): builds the set-theoretic intersection of two
	tables. Given the tables <classname>R</classname> and
	<classname>S</classname>,
	<classname>R</classname> &cap; <classname>S</classname> is the
	set of tuples
	that are in <classname>R</classname> and in
	<classname>S</classname>.
	We again require that <classname>R</classname> and 
	<classname>S</classname> have the
	same arity.
d488 6
a493 6
	DIFFERENCE (&minus; or &setmn;): builds the set difference of
	two tables. Let <classname>R</classname> and <classname>S</classname>
	again be two tables with the same
	arity. <classname>R</classname> - <classname>S</classname>
	is the set of tuples in <classname>R</classname> but not in
	<classname>S</classname>.
d499 9
a507 9
	JOIN (&prod;): connects two tables by their common
	attributes. Let <classname>R</classname> be a table with the 
	attributes <classname>A</classname>,<classname>B</classname> 
	and <classname>C</classname> and
	let <classname>S</classname> be a table with the attributes
	<classname>C</classname>,<classname>D</classname>
	and <classname>E</classname>. There is one
	attribute common to both relations,
	the attribute <classname>C</classname>. 
d509 2
a510 2
	<classname>R</classname> &prod; <classname>S</classname> =
	&pi;<subscript><classname>R</classname>.<classname>A</classname>,<classname>R</classname>.<classname>B</classname>,<classname>R</classname>.<classname>C</classname>,<classname>S</classname>.<classname>D</classname>,<classname>S</classname>.<classname>E</classname></subscript>(&sigma;<subscript><classname>R</classname>.<classname>C</classname>=<classname>S</classname>.<classname>C</classname></subscript>(<classname>R</classname> &times; <classname>S</classname>)).
d512 11
a522 11
	R &prod; S = &pi;<subscript>R.A,R.B,R.C,S.D,S.E</subscript>(&sigma;<subscript>R.C=S.C</subscript>(R &times; S)).
	What are we doing here? We first calculate the Cartesian
	product
	<classname>R</classname> &times; <classname>S</classname>.
	Then we select those tuples whose values for the common
	attribute <classname>C</classname> are equal
	(&sigma;<subscript>R.C = S.C</subscript>).
	Now we have a table
	that contains the attribute <classname>C</classname>
	two times and we correct this by
	projecting out the duplicate column.
d526 1
a526 1
	<title id="join-example">An Inner Join</title>
d528 4
a531 4
	<para>
	 Let's have a look at the tables that are produced by evaluating the steps
	 necessary for a join.
	 Let the following two tables be given:
d533 1
a533 1
	 <programlisting>
d540 2
a541 2
	 </programlisting>
	</para>
d545 3
a547 3
	First we calculate the Cartesian product
	<classname>R</classname> &times; <classname>S</classname> and
	get:
d549 1
a549 1
	<programlisting>
d559 1
a559 1
	</programlisting>
d563 3
a565 3
	After the selection
	&sigma;<subscript>R.C=S.C</subscript>(R &times; S)
	we get:
d567 1
a567 1
	<programlisting>
d572 1
a572 1
	</programlisting>
d576 5
a580 5
	To remove the duplicate column
	<classname>S</classname>.<classname>C</classname>
	we project it out by the following operation:
	&pi;<subscript>R.A,R.B,R.C,S.D,S.E</subscript>(&sigma;<subscript>R.C=S.C</subscript>(R &times; S))
	and get:
d582 1
a582 1
	<programlisting>
d587 1
a587 1
	</programlisting>
d593 5
a597 5
	DIVIDE (&divide;): Let <classname>R</classname> be a table
	with the attributes A, B, C, and D and let
	<classname>S</classname> be a table with the attributes
	C and D.
	Then we define the division as:
d599 1
a599 1
	<programlisting>
d601 1
a601 1
	</programlisting>
d603 1
a603 1
	such that
d605 8
a612 8
	where
	t<subscript>r</subscript>(x,y)
	denotes a
	tuple of table <classname>R</classname> that consists only of
	the components <literal>x</literal> and <literal>y</literal>.
	Note that the tuple <literal>t</literal> only consists of the
	components <classname>A</classname> and
	<classname>B</classname> of relation <classname>R</classname>.
d616 1
a616 1
	Given the following tables
d618 1
a618 1
	<programlisting>
d628 1
a628 1
	</programlisting>
d630 2
a631 2
	R &divide; S
	is derived as
d633 1
a633 1
	<programlisting>
d638 1
a638 1
	</programlisting>
d694 3
a696 3
	The <firstterm>Domain Relational Calculus</firstterm>
	(<acronym>DRC</acronym>), where variables
	stand for components (attributes) of the tuples.
d702 2
a703 2
	The <firstterm>Tuple Relational Calculus</firstterm>
	(<acronym>TRC</acronym>), where variables stand for tuples.
d886 2
a887 2
	To retrieve all tuples from table PART where the attribute PRICE is
	greater than 10 we formulate the following query:
d889 1
a889 1
	<programlisting>
d892 1
a892 1
	</programlisting>
d894 1
a894 1
	and get the table:
d896 1
a896 1
	<programlisting>
d901 1
a901 1
	</programlisting>
d905 4
a908 4
	Using <quote>*</quote> in the <command>SELECT</command> statement
	will deliver all attributes from the table. If we want to retrieve
	only the attributes PNAME and PRICE from table PART we use the
	statement:
d910 1
a910 1
	<programlisting>
d914 1
a914 1
	</programlisting>
d916 1
a916 1
	In this case the result is:
d918 1
a918 1
	<programlisting>
d923 1
a923 1
	</programlisting>
d925 4
a928 4
	Note that the <acronym>SQL</acronym> <command>SELECT</command>
	corresponds to the <quote>projection</quote> in relational algebra
	not to the <quote>selection</quote> (see <xref linkend="rel-alg"
	endterm="rel-alg"> for more details).
d932 2
a933 2
	The qualifications in the WHERE clause can also be logically connected
	using the keywords OR, AND, and NOT:
d935 1
a935 1
	<programlisting>
d940 1
a940 1
	</programlisting>
d942 1
a942 1
	will lead to the result:
d944 1
a944 1
	<programlisting>
d948 1
a948 1
	</programlisting>
d952 3
a954 3
	Arithmetic operations can be used in the target list and in the WHERE
	clause. For example if we want to know how much it would cost if we
	take two pieces of a part we could use the following query:
d956 1
a956 1
	<programlisting>
d960 1
a960 1
	</programlisting>
d962 1
a962 1
	and we get:
d964 1
a964 1
	<programlisting>
d970 1
a970 1
	</programlisting>
d972 6
a977 6
	Note that the word DOUBLE after the keyword AS is the new title of the
	second column. This technique can be used for every element of the
	target list to assign a new title to the resulting
	column. This new title
	is often referred to as alias. The alias cannot be used throughout the
	rest of the query.
d1035 3
a1037 3
	 <para>
	 Another way to perform joins is to use the SQL JOIN syntax as follows:
	 <programlisting>
d1039 5
a1043 5
	JOIN sells USING (sno)
	JOIN part USING (pno);
	</programlisting>
	giving again:
	<programlisting>
d1055 2
a1056 2
	 </programlisting>
	 </para>
d1058 16
a1073 16
	 <para>
	 A joined table, created using JOIN syntax, is a table reference list
	 item that occurs in a FROM clause and before any WHERE, GROUP BY,
	 or HAVING clause.  Other table references, including table names or
	 other JOIN clauses, can be included in the FROM clause if separated
	 by commas.  JOINed tables are logically like any other
	 table listed in the FROM clause.
	 </para>

	 <para>
	  SQL JOINs come in two main types, CROSS JOINs (unqualified joins)
	  and <firstterm>qualified JOINs</>.  Qualified joins can be further
	  subdivided based on the way in which the <firstterm>join condition</>
	  is specified (ON, USING, or NATURAL) and the way in which it is
	  applied (INNER or OUTER join).
	 </para>
d1079 5
a1083 5
	        <listitem>
			<cmdsynopsis>
			    <arg choice="req"> <replaceable class="parameter">T1</replaceable> </arg>
			    <command> CROSS JOIN </command>
			    <arg choice="req"> <replaceable class="parameter">T2</replaceable> </arg>
d1086 86
a1171 86
			<para>
			A cross join takes two tables T1 and T2 having N and M rows
			respectively, and returns a joined table containing all
			N*M possible joined rows. For each row R1 of T1, each row
			R2 of T2 is joined with R1 to yield a joined table row JR
			consisting of all fields in R1 and R2. A CROSS JOIN is
			equivalent to an INNER JOIN ON TRUE.
			</para>
			</listitem>
		</varlistentry>

		<varlistentry>
		    <term>Qualified JOINs</term>
		    <listitem>

			<cmdsynopsis>
			<arg choice="req"> <replaceable class="parameter">T1</replaceable> </arg>
			<arg choice="opt"> NATURAL </arg>
			<group choice="opt">
				<arg choice="opt"> INNER </arg>
				<arg>
				<group choice="req">
					<arg choice="plain"> LEFT </arg>
					<arg choice="plain"> RIGHT </arg>
					<arg choice="plain"> FULL </arg>
				</group>
				<arg choice="opt"> OUTER </arg>
      				</arg>
     			</group>
			<command> JOIN </command>
			<arg choice="req"> <replaceable class="parameter">T2</replaceable> </arg>
			<group choice="req">
				<arg> ON <replaceable>search condition</replaceable></arg>
				<arg> USING ( <replaceable>join column list</replaceable> ) </arg>
			</group>
			</cmdsynopsis>

			<para>
			A qualified JOIN must specify its join condition
			by providing one (and only one) of NATURAL, ON, or
			USING.  The ON clause
			takes a <replaceable>search condition</replaceable>,
			which is the same as in a WHERE clause.  The USING
			clause takes a comma-separated list of column names,
			which the joined tables must have in common, and joins
			the tables on equality of those columns.  NATURAL is
			shorthand for a USING clause that lists all the common
			column names of the two tables.  A side-effect of both
			USING and NATURAL is that only one copy of each joined
			column is emitted into the result table (compare the
			relational-algebra definition of JOIN, shown earlier).
			</para>

			<!-- begin join semantics -->
			<variablelist>
			<varlistentry>
				<term>
					<cmdsynopsis>
						<arg> INNER </arg>
						<command> JOIN </command>
					</cmdsynopsis>
				</term>
				<listitem>
				<para>
				For each row R1 of T1, the joined table has a row for each row
				in T2 that satisfies the join condition with R1. 
				</para>
				<tip>
				<para>
					The words INNER and OUTER are optional for all JOINs.
					INNER is the default.  LEFT, RIGHT, and FULL imply an
					OUTER JOIN.
					</para>
				</tip>
				</listitem>
    		</varlistentry>
			<varlistentry>
				<term>
					<cmdsynopsis>
						<arg choice="plain"> LEFT </arg>
						<arg> OUTER </arg>
						<command> JOIN </command>
					</cmdsynopsis>
     			</term>
				<listitem>
				<para>
d1174 20
a1193 20
				condition with any row in T2, an additional joined row is
				returned with null fields in the columns from T2.
				</para>
				<tip>
					<para>
					The joined table unconditionally has a row for each row in T1.
					</para>
				</tip>
				</listitem>
			</varlistentry>
			<varlistentry>
				<term>
					<cmdsynopsis>
						<arg choice="plain"> RIGHT </arg>
						<arg> OUTER </arg>
						<command> JOIN </command>
      				</cmdsynopsis>
          		</term>
				<listitem>
				<para>
d1196 20
a1215 20
				condition with any row in T1, an additional joined row is
				returned with null fields in the columns from T1.
				</para>
				<tip>
					<para>
					The joined table unconditionally has a row for each row in T2.
					</para>
				</tip>
				</listitem>
    		</varlistentry>
			<varlistentry>
				<term>
					<cmdsynopsis>
						<arg choice="plain"> FULL </arg>
						<arg> OUTER </arg>
						<command> JOIN </command>
      				</cmdsynopsis>
          		</term>
            	<listitem>
				<para>
d1218 2
a1219 2
				condition with any row in T2, an additional joined row is
				returned with null fields in the columns from T2.
d1221 13
a1233 13
				condition with any row in T1, an additional joined row is
				returned with null fields in the columns from T1.
				</para>
				<tip>
					<para>
        			The joined table unconditionally has a row for every row of T1
					and a row for every row of T2.
					</para>
				</tip>
				</listitem>
    		</varlistentry>
			</variablelist>
			<!-- end join semantics -->
d1235 1
a1235 1
			</listitem>
d1237 1
a1237 1
	 </variablelist>
d1239 7
a1245 7
	 <para>
	 JOINs of all types can be chained together or nested where either or both of
	 <replaceable class="parameter">T1</replaceable> and
	 <replaceable class="parameter">T2</replaceable> can be JOINed tables.
	 Parenthesis can be used around JOIN clauses to control the order
	 of JOINs which are otherwise processed left to right.
	 </para>
d1267 2
a1268 2
	If we want to know the average cost of all parts in table PART we use
	the following query:
d1270 1
a1270 1
	<programlisting>
d1273 1
a1273 1
	</programlisting>
d1277 1
a1277 1
	The result is:
d1279 1
a1279 1
	<programlisting>
d1283 1
a1283 1
	</programlisting>
d1287 2
a1288 2
	If we want to know how many parts are defined in table PART we use
	the statement:
d1290 1
a1290 1
	<programlisting>
d1293 1
a1293 1
	</programlisting>
d1295 1
a1295 1
	and get:
d1297 1
a1297 1
	<programlisting>
d1301 1
a1301 1
	</programlisting>
d1335 2
a1336 2
	If we want to know how many parts are sold by every supplier we
	formulate the query:
d1338 1
a1338 1
	<programlisting>
d1343 1
a1343 1
	</programlisting>
d1345 1
a1345 1
	and get:
d1347 1
a1347 1
	<programlisting>
d1354 1
a1354 1
	</programlisting>
d1358 3
a1360 3
	Now let's have a look of what is happening here.
	First the join of the
	tables SUPPLIER and SELLS is derived:
d1362 1
a1362 1
	<programlisting>
d1373 1
a1373 1
	</programlisting>
d1377 2
a1378 2
	Next we partition the tuples into groups by putting all tuples
	together that agree on both attributes S.SNO and S.SNAME:
d1380 1
a1380 1
	<programlisting>
d1394 1
a1394 1
	</programlisting>
d1398 3
a1400 3
	In our example we got four groups and now we can apply the aggregate
	function COUNT to every group leading to the final result of the query
	given above.
d1442 2
a1443 2
	If we want only those suppliers selling more than one part we use the
	query:
d1445 1
a1445 1
	<programlisting>
d1451 1
a1451 1
	</programlisting>
d1453 1
a1453 1
	and get:
d1455 1
a1455 1
	<programlisting>
d1461 1
a1461 1
	</programlisting>
d1481 2
a1482 2
	If we want to know all parts having a greater price than the part
	named 'Screw' we use the query:
d1484 1
a1484 1
	<programlisting>
d1489 1
a1489 1
	</programlisting>
d1493 1
a1493 1
	The result is:
d1495 1
a1495 1
	<programlisting>
d1500 1
a1500 1
	</programlisting>
d1504 12
a1515 12
	When we look at the above query we can see the keyword
	<command>SELECT</command> two times. The first one at the
	beginning of the query - we will refer to it as outer
	<command>SELECT</command> - and the one in the WHERE clause which
	begins a nested query - we will refer to it as inner
	<command>SELECT</command>. For every tuple of the outer
	<command>SELECT</command> the inner <command>SELECT</command> has
	to be evaluated. After every evaluation we know the price of the
	tuple named 'Screw' and we can check if the price of the actual
	tuple is greater.  (Actually, in this example the inner query need
	only be evaluated once, since it does not depend on the state of
	the outer query.)
d1519 2
a1520 2
	If we want to know all suppliers that do not sell any part 
	(e.g. to be able to remove these suppliers from the database) we use:
d1522 1
a1522 1
	<programlisting>
d1528 1
a1528 1
	</programlisting>
d1532 7
a1538 7
	In our example the result will be empty because every supplier
	sells at least one part. Note that we use S.SNO from the outer
	<command>SELECT</command> within the WHERE clause of the inner
	<command>SELECT</command>. Here the subquery must be evaluated
	afresh for each tuple from the outer query, i.e. the value for
	S.SNO is always taken from the current tuple of the outer
	<command>SELECT</command>.
d1560 1
a1560 1
	suppliers, we cannot write MAX(AVG(PRICE)), but we can write:
d1562 1
a1562 1
	<programlisting>
d1569 1
a1569 1
	</programlisting>
d1571 2
a1572 2
	The subquery returns one row per supplier (because of its GROUP BY)
	and then we aggregate over those rows in the outer query.
d1589 1
a1589 1
	The following query is an example for UNION:
d1591 1
a1591 1
	<programlisting>
d1599 1
a1599 1
	</programlisting>
d1603 1
a1603 1
	<programlisting>
d1608 1
a1608 1
	</programlisting>
d1612 1
a1612 1
	Here is an example for INTERSECT:
d1614 1
a1614 1
	<programlisting>
d1622 1
a1622 1
	</programlisting>
d1624 1
a1624 1
	gives the result:
d1626 1
a1626 1
	<programlisting>
d1630 1
a1630 1
	</programlisting>
d1632 1
a1632 1
	The only tuple returned by both parts of the query is the one having SNO=2.
d1636 1
a1636 1
	Finally an example for EXCEPT:
d1638 1
a1638 1
	<programlisting>
d1646 1
a1646 1
	</programlisting>
d1648 1
a1648 1
	gives the result:
d1650 1
a1650 1
	<programlisting>
d1655 1
a1655 1
	</programlisting>
d1689 3
a1691 3
	To create the tables defined in
	<xref linkend="supplier-fig" endterm="supplier-fig"> the
	following <acronym>SQL</acronym> statements are used:
d1693 1
a1693 1
	<programlisting>
d1711 1
a1711 1
	</programlisting>
d1726 3
a1728 3
	<para>
	 INTEGER: signed fullword binary integer (31 bits precision).
	</para>
d1732 3
a1734 3
	<para>
	 SMALLINT: signed halfword binary integer (15 bits precision).
	</para>
d1738 10
a1747 10
	<para>
	 DECIMAL (<replaceable class="parameter">p</replaceable>[,<replaceable class="parameter">q</replaceable>]):
	 signed packed decimal number of up to
	 <replaceable class="parameter">p</replaceable>
	 digits, with
	 <replaceable class="parameter">q</replaceable>
	 digits to the right of the decimal point.
	 If <replaceable class="parameter">q</replaceable>
	 is omitted it is assumed to be 0.
	</para>
d1751 3
a1753 3
	<para>
	 FLOAT: signed doubleword floating point number.
	</para>
d1757 5
a1761 5
	<para>
	 VARCHAR(<replaceable class="parameter">n</replaceable>):
	 varying length character string of maximum length
	 <replaceable class="parameter">n</replaceable>.
	</para>
d1765 5
a1769 5
	<para>
	 CHAR(<replaceable class="parameter">n</replaceable>):
	 fixed length character string of length
	 <replaceable class="parameter">n</replaceable>.
	</para>
d1805 2
a1806 2
	To create an index named I on attribute SNAME of relation SUPPLIER
	we use the following statement:
d1814 5
a1818 5
	The created index is maintained automatically, i.e. whenever a new
	tuple is inserted into the relation SUPPLIER the index I is
	adapted. Note that the only changes a user can perceive when an
	index is present are increased speed for <command>SELECT</command>
	and decreases in speed of updates.
d2092 4
a2095 4
	There are queries that cannot be formulated using pure <acronym>SQL</acronym>
	(i.e. recursive queries). To be able to perform such queries we need a
	host language with a greater expressive power than
	<acronym>SQL</acronym>.
d2101 5
a2105 5
	We simply want to access a database from some application that
	is written in the host language (e.g. a ticket reservation system
	with a graphical user interface is written in C and the information
	about which tickets are still left is stored in a database that can be
	accessed using embedded <acronym>SQL</acronym>).
@


1.44
log
@Update documentation on may/can/might:

Standard English uses "may", "can", and "might" in different ways:

        may - permission, "You may borrow my rake."

        can - ability, "I can lift that log."

        might - possibility, "It might rain today."

Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice.  Similarly, "It may crash" is better stated, "It might crash".

Also update two error messages mentioned in the documenation to match.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.43 2007/01/09 02:14:10 tgl Exp $ -->
d1560 1
a1560 1
	suppliers, we can't write MAX(AVG(PRICE)), but we can write:
@


1.43
log
@Support ORDER BY ... NULLS FIRST/LAST, and add ASC/DESC/NULLS FIRST/NULLS LAST
per-column options for btree indexes.  The planner's support for this is still
pretty rudimentary; it does not yet know how to plan mergejoins with
nondefault ordering options.  The documentation is pretty rudimentary, too.
I'll work on improving that stuff later.

Note incompatible change from prior behavior: ORDER BY ... USING will now be
rejected if the operator is not a less-than or greater-than member of some
btree opclass.  This prevents less-than-sane behavior if an operator that
doesn't actually define a proper sort ordering is selected.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.42 2006/09/16 00:30:15 momjian Exp $ -->
d176 1
a176 1
    The tables PART and SUPPLIER may be regarded as
d178 1
a178 1
    SELLS may be regarded as a <firstterm>relationship</firstterm>
d952 1
a952 1
	Arithmetic operations may be used in the target list and in the WHERE
d1062 1
a1062 1
	 other JOIN clauses, may be included in the FROM clause if separated
d1242 1
a1242 1
	 <replaceable class="parameter">T2</replaceable> may be JOINed tables.
d1408 1
a1408 1
      the attributes being grouped by.  Other attributes may only be used
d1828 1
a1828 1
      A view may be regarded as a <firstterm>virtual table</firstterm>,
@


1.42
log
@Remove emacs info from footer of SGML files.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.41 2006/07/27 19:52:04 tgl Exp $ -->
d863 1
a863 1
    [ ORDER BY <replaceable class="PARAMETER">expression</replaceable> [ ASC | DESC | USING <replaceable class="PARAMETER">operator</replaceable> ] [, ...] ]
@


1.41
log
@Aggregate functions now support multiple input arguments.  I also took
the opportunity to treat COUNT(*) as a zero-argument aggregate instead
of the old hack that equated it to COUNT(1); this is materially cleaner
(no more weird ANYOID cases) and ought to be at least a tiny bit faster.
Original patch by Sergey Koposov; review, documentation, simple regression
tests, pg_dump and psql support by moi.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.40 2006/04/30 18:30:38 tgl Exp $ -->
a2148 17

<!-- 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:
-->
@


1.40
log
@Improve the representation of FOR UPDATE/FOR SHARE so that we can
support both FOR UPDATE and FOR SHARE in one command, as well as both
NOWAIT and normal WAIT behavior.  The more general code is actually
simpler and cleaner.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.39 2006/03/10 19:10:49 momjian Exp $ -->
d1250 1
a1250 1
     <title id="aggregates-tutorial">Aggregate Operators</title>
d1253 4
a1256 4
      <acronym>SQL</acronym> provides aggregate operators (e.g. AVG,
      COUNT, SUM, MIN, MAX) that take an expression as argument.  The
      expression is evaluated at each row that satisfies the WHERE
      clause, and the aggregate operator is calculated over this set
d1314 2
a1315 2
      aggregate operators described above can be applied to the groups &mdash;
      i.e. the value of the aggregate operator is no longer calculated over
d1317 1
a1317 1
      group. Thus the aggregate operator is evaluated separately for every
d1399 1
a1399 1
	operator COUNT to every group leading to the final result of the query
d1407 1
a1407 1
      operators to make sense the target list can only refer directly to
d1409 1
a1409 1
      inside the argument of an aggregate function.  Otherwise there would
@


1.39
log
@Make $PostgreSQL CVS tags consistent for SGML files.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/advanced.sgml,v 1.49 2005/04/09 03:52:43 momjian Exp $ -->
d866 1
a866 1
    [ FOR { UPDATE | SHARE } [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT ] ]
@


1.38
log
@Add NOWAIT option to SELECT FOR UPDATE/SHARE.
Original patch by Hans-Juergen Schoenig, revisions by Karel Zak
and Tom Lane.
@
text
@d1 1
a1 3
<!--
$PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.37 2005/07/14 06:17:35 neilc Exp $
-->
@


1.37
log
@This doc patch replaces all inappropriate references to SQL:1999 when it
is used as if it were the latest (and/or still valid) SQL standard.
SQL:2003 is used in its place. Patch from Simon Riggs.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.36 2005/04/28 21:47:09 tgl Exp $
d868 1
a868 1
    [ FOR { UPDATE | SHARE } [ OF <replaceable class="PARAMETER">class_name</replaceable> [, ...] ] ]
@


1.36
log
@Implement sharable row-level locks, and use them for foreign key references
to eliminate unnecessary deadlocks.  This commit adds SELECT ... FOR SHARE
paralleling SELECT ... FOR UPDATE.  The implementation uses a new SLRU
data structure (managed much like pg_subtrans) to represent multiple-
transaction-ID sets.  When more than one transaction is holding a shared
lock on a particular row, we create a MultiXactId representing that set
of transactions and store its ID in the row's XMAX.  This scheme allows
an effectively unlimited number of row locks, just as we did before,
while not costing any extra overhead except when a shared lock actually
has to be shared.   Still TODO: use the regular lock manager to control
the grant order when multiple backends are waiting for a row lock.

Alvaro Herrera and Tom Lane.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.35 2005/02/21 02:21:03 neilc Exp $
d101 1
a101 2
   possible. This is a very complex task and therefore the completion of
   the new standard can not be expected before 1999.
@


1.35
log
@Updates to the bibliography. Patch from Michael Fuhr.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.34 2005/01/22 22:56:36 momjian Exp $
d869 1
a869 1
    [ FOR UPDATE [ OF <replaceable class="PARAMETER">class_name</replaceable> [, ...] ] ]
@


1.34
log
@More < and > cleanups converted to ampersands.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.33 2004/11/15 06:32:14 neilc Exp $
d650 1
a650 1
     [<xref linkend="DATE94" endterm="DATE94">].
d717 1
a717 1
     <xref linkend="DATE94" endterm="DATE94">
d775 1
a775 1
     <xref linkend="DATE94" endterm="DATE94">
d2079 1
a2079 1
     <xref linkend="DATE94" endterm="DATE94">.
d2145 1
a2145 1
     <xref linkend="DATE94" endterm="DATE94">,
@


1.33
log
@Replace "--" and "---" with "&mdash;" as appropriate, for better-looking
output.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.32 2003/11/29 19:51:37 pgsql Exp $
d894 1
a894 1
    WHERE PRICE > 10;
d916 1
a916 1
    WHERE PRICE > 10;
d942 1
a942 1
         (PRICE = 0 OR PRICE <= 15);
d962 1
a962 1
    WHERE PRICE * 2 < 50;
d1453 1
a1453 1
    HAVING COUNT(SE.PNO) > 1;
d1490 1
a1490 1
    WHERE PRICE > (SELECT PRICE FROM PART
d1620 1
a1620 1
    WHERE S.SNO > 1
d1624 1
a1624 1
    WHERE S.SNO < 3;
d1644 1
a1644 1
    WHERE S.SNO > 1
d1648 1
a1648 1
    WHERE S.SNO > 3;
@


1.33.4.1
log
@More < and > cleanups converted to ampersands.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.33 2004/11/15 06:32:14 neilc Exp $
d894 1
a894 1
    WHERE PRICE &gt; 10;
d916 1
a916 1
    WHERE PRICE &gt; 10;
d942 1
a942 1
         (PRICE = 0 OR PRICE &lt;= 15);
d962 1
a962 1
    WHERE PRICE * 2 &lt; 50;
d1453 1
a1453 1
    HAVING COUNT(SE.PNO) &gt; 1;
d1490 1
a1490 1
    WHERE PRICE &gt; (SELECT PRICE FROM PART
d1620 1
a1620 1
    WHERE S.SNO &gt; 1
d1624 1
a1624 1
    WHERE S.SNO &lt; 3;
d1644 1
a1644 1
    WHERE S.SNO &gt; 1
d1648 1
a1648 1
    WHERE S.SNO &gt; 3;
@


1.32
log
@
$Header: -> $PostgreSQL Changes ...
@
text
@d2 1
a2 1
$PostgreSQL: /cvsroot/pgsql-server/doc/src/sgml/sql.sgml,v 1.31 2003/08/10 01:20:34 tgl Exp $
d1317 1
a1317 1
      aggregate operators described above can be applied to the groups ---
@


1.31
log
@Make various links point to specific places instead of entire parts
(doubtless these are hangovers from the old separate-books days).
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/sql.sgml,v 1.30 2003/03/27 16:51:26 momjian Exp $
@


1.30
log
@This patch implements holdable cursors, following the proposal
(materialization into a tuple store) discussed on pgsql-hackers earlier.
I've updated the documentation and the regression tests.

Notes on the implementation:

- I needed to change the tuple store API slightly -- it assumes that it
won't be used to hold data across transaction boundaries, so the temp
files that it uses for on-disk storage are automatically reclaimed at
end-of-transaction. I added a flag to tuplestore_begin_heap() to control
this behavior. Is changing the tuple store API in this fashion OK?

- in order to store executor results in a tuple store, I added a new
CommandDest. This works well for the most part, with one exception: the
current DestFunction API doesn't provide enough information to allow the
Executor to store results into an arbitrary tuple store (where the
particular tuple store to use is chosen by the call site of
ExecutorRun). To workaround this, I've temporarily hacked up a solution
that works, but is not ideal: since the receiveTuple DestFunction is
passed the portal name, we can use that to lookup the Portal data
structure for the cursor and then use that to get at the tuple store the
Portal is using. This unnecessarily ties the Portal code with the
tupleReceiver code, but it works...

The proper fix for this is probably to change the DestFunction API --
Tom suggested passing the full QueryDesc to the receiveTuple function.
In that case, callers of ExecutorRun could "subclass" QueryDesc to add
any additional fields that their particular CommandDest needed to get
access to. This approach would work, but I'd like to think about it for
a little bit longer before deciding which route to go. In the mean time,
the code works fine, so I don't think a fix is urgent.

- (semi-related) I added a NO SCROLL keyword to DECLARE CURSOR, and
adjusted the behavior of SCROLL in accordance with the discussion on
-hackers.

- (unrelated) Cleaned up some SGML markup in sql.sgml, copy.sgml

Neil Conway
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/sql.sgml,v 1.29 2003/02/19 04:06:28 momjian Exp $
d5 1
a5 1
 <chapter id="sql">
@


1.29
log
@This patch makes the following changes to the documentation:

- more work from the SGML police

- some grammar improvements: rewriting a paragraph or two, replacing
contractions where (IMHO) appropriate

- fix missing utility commands in lock mode docs

- improve CLUSTER, REINDEX, SET SESSION AUTHORIZATION ref pages

Neil Conway
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/sql.sgml,v 1.28 2003/01/15 18:01:05 momjian Exp $
d854 1
a854 1
     SELECT statement,
d884 1
a884 1
      Here are some simple examples using a SELECT statement:
d908 4
a911 3
	Using <quote>*</quote> in the SELECT statement will deliver all attributes from
	the table. If we want to retrieve only the attributes PNAME and PRICE
	from table PART we use the statement:
d928 3
a930 3
	Note that the <acronym>SQL</acronym> SELECT corresponds to the
	<quote>projection</quote> in relational algebra not to the
	<quote>selection</quote> (see <xref linkend="rel-alg"
d1256 9
a1264 9
      <acronym>SQL</acronym> provides aggregate operators
      (e.g. AVG, COUNT, SUM, MIN, MAX) that
      take an expression as argument.  The expression is evaluated at
      each row that satisfies the WHERE clause, and the aggregate operator
      is calculated over this set of input values.  Normally, an aggregate
      delivers a single result for a whole SELECT statement.  But if
      grouping is specified in the query, then a separate calculation is done
      over the rows of each group, and an aggregate result is delivered per
      group (see next section).
d1417 6
a1422 5
      Also observe that it makes no sense to ask for an aggregate of an
      aggregate, e.g., AVG(MAX(sno)), because a SELECT only does one pass
      of grouping and aggregation.  You can get a result of this kind by
      using a temporary table or a sub-SELECT in the FROM clause to
      do the first level of aggregation.
d1507 12
a1518 10
	When we look at the above query we can see
	the keyword SELECT two times. The first one at the beginning of the
	query - we will refer to it as outer SELECT - and the one in the WHERE
	clause which begins a nested query - we will refer to it as inner
	SELECT. For every tuple of the outer SELECT the inner SELECT has to be
	evaluated. After every evaluation we know the price of the tuple named
	'Screw' and we can check if the price of the actual tuple is
	greater.  (Actually, in this example the inner query need only be
	evaluated once, since it does not depend on the state of the outer
	query.)
d1535 7
a1541 5
	In our example the result will be empty because every supplier sells
	at least one part. Note that we use S.SNO from the outer SELECT within
	the WHERE clause of the inner SELECT. Here the subquery must be
	evaluated afresh for each tuple from the outer query, i.e. the value for
	S.SNO is always taken from the current tuple of the outer SELECT. 
d1679 1
a1679 1
      CREATE TABLE command is:
d1795 1
a1795 1
      the CREATE INDEX command is used. The syntax is:
d1817 5
a1821 4
	The created index is maintained automatically, i.e. whenever a new tuple
	is inserted into the relation SUPPLIER the index I is adapted. Note
	that the only changes a user can perceive when an index is present
	are increased speed for SELECT and decreases in speed of updates.
d1926 1
a1926 1
      DROP TABLE command is used:
d1942 1
a1942 1
      The DROP INDEX command is used to destroy an index:
d1950 2
a1951 1
      Finally to destroy a given view use the command DROP VIEW:
d2005 1
a2005 1
      UPDATE command is used. The syntax is:
d2137 1
a2137 1
     After that we can use the FETCH command to
@


1.28
log
@Reorder VARCHAR() to appear before CHAR() in docs.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/sql.sgml,v 1.27 2002/08/28 14:35:36 momjian Exp $
d27 1
a27 1
   The name "<acronym>SQL</acronym>" is an abbreviation for
d75 1
a75 1
   informally, as "<abbrev>SQL/86</abbrev>". In 1989 the original
d78 1
a78 1
   "<abbrev>SQL/89</abbrev>". Also in 1989, a related standard called
d89 2
a90 2
   ratified standard - "International Standard ISO/IEC 9075:1992,
   Database Language <acronym>SQL</acronym>" - in late 1992.
d92 2
a93 2
   normally meant when people refer to "the <acronym>SQL</acronym>
   standard". A detailed
d771 2
a772 2
     1972. This proof is based on an algorithm ("Codd's reduction
     algorithm") by which an arbitrary expression of the relational
d781 6
a786 5
     It is sometimes said that languages based on the relational calculus
     are "higher level" or "more declarative" than languages based on
     relational algebra because the algebra (partially) specifies the order
     of operations while the calculus leaves it to a compiler or
     interpreter to determine the most efficient order of evaluation.
d874 4
a877 3
     Now we will illustrate the complex syntax of the SELECT statement
     with various examples. The tables used for the examples are defined in
     <xref linkend="supplier-fig" endterm="supplier-fig">.
d908 1
a908 1
	Using "*" in the SELECT statement will deliver all attributes from
d927 4
a930 3
	Note that the <acronym>SQL</acronym> SELECT corresponds to the 
	"projection" in relational algebra not to the "selection"
	(see <xref linkend="rel-alg" endterm="rel-alg"> for more details).
@


1.27
log
@Allow FOR UPDATE to appear after LIMIT/OFFSET to match MySQL syntax and as
a more logical ordering.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/sql.sgml,v 1.26 2002/03/15 16:16:31 momjian Exp $
d1752 2
a1753 2
	 CHAR(<replaceable class="parameter">n</replaceable>):
	 fixed length character string of length
d1760 2
a1761 2
	 VARCHAR(<replaceable class="parameter">n</replaceable>):
	 varying length character string of maximum length
d1765 1
@


1.26
log
@Back out EXCEPT/DIFFERENCE patch.  Seems I forgot the details of this.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.24 2001/10/23 16:42:36 momjian Exp $
a865 1
    [ FOR UPDATE [ OF <replaceable class="PARAMETER">class_name</replaceable> [, ...] ] ]
d868 1
@


1.25
log
@Fix for docs from Patrick Welche:

! 	DIFFERENCE (&minus; or &setmn;): builds the set difference of
  	two tables. Let <classname>R</classname> and
<classname>S</classname>
again be two tables with the same
  	arity. <classname>R</classname> - <classname>S</classname>
--- 488,494 ----

        <listitem>
        <para>
! 	EXCEPT (&minus; or &setmn;): builds the set difference of
@
text
@d491 1
a491 1
	EXCEPT (&minus; or &setmn;): builds the set difference of
@


1.24
log
@Move ALL out of UNION|INTERSECT|EXCEPT syntax.

Alvaro Herrera
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.23 2001/10/20 02:55:38 momjian Exp $
d491 1
a491 1
	DIFFERENCE (&minus; or &setmn;): builds the set difference of
@


1.23
log
@Remove LIMIT #,# and suggest LIMIT # OFFSET #, per mailing list discussion.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.22 2001/09/23 03:39:01 momjian Exp $
d864 1
a864 1
    [ { UNION | INTERSECT | EXCEPT [ ALL ] } <replaceable class="PARAMETER">select</replaceable> ]
@


1.22
log
@Implement TODO item:

	* Change LIMIT val,val to offset,limit to match MySQL

Documentation updates too.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.21 2001/05/22 16:00:00 petere Exp $
d867 1
a867 1
    [ LIMIT [ <replaceable class="PARAMETER">start</replaceable> , ] { <replaceable class="PARAMETER">count</replaceable> | ALL } ]
@


1.21
log
@more indices -> indexes
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.20 2001/03/24 23:03:26 petere Exp $
d867 2
a868 1
    [ LIMIT { <replaceable class="PARAMETER">count</replaceable> | ALL } [ { OFFSET | , } <replaceable class="PARAMETER">start</replaceable> ]]
@


1.20
log
@minor copy editing
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.19 2001/02/15 04:10:54 tgl Exp $
d1772 1
a1772 1
      Indices are used to speed up access to a relation. If a relation <classname>R</classname>
@


1.19
log
@Improve documentation of JOIN syntax.  Explain NATURAL as an alternative
to ON and USING for specifying the join condition, not as an independent
kind of join semantics.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.18 2001/01/27 05:07:28 momjian Exp $
d1413 1
a1413 1
      aggregate, eg, AVG(MAX(sno)), because a SELECT only does one pass
@


1.18
log
@in the tutorial, chapter 2., "Relational Data Model Formalities"
(sql490.htm), there is

"set of all k-tuples v1, v2, ... vk, such that v1 [isin] D1, v1 [isin] D1"

i assume it should be
"set of all k-tuples v1, v2, ... vk, such that v1 [isin] D1, v2 [isin] D2"

Divide by Zero
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.17 2001/01/09 16:05:21 momjian Exp $
d1066 5
a1070 9
	 JOINs of all types can be chained together or nested where either or both of
	 <replaceable class="parameter">T1</replaceable> and
	 <replaceable class="parameter">T2</replaceable> may be JOINed tables.
	 A Qualified JOIN may be JOINed to another table (or JOINed table)
	 following its join specification, which consists of either an
	 ON <replaceable>search condition</replaceable> or
	 USING ( <replaceable>join column list</replaceable> ) clause.
	 Parenthesis can be used around JOIN clauses to control the order
	 of JOINs which are otherwise processed left to right.
d1080 1
a1080 2
				<arg choice="plain">CROSS</arg>
			    <command> JOIN </command>
d1086 2
a1087 2
			respectively, and returns a joined table containing a cross
			product, NxM, of joined rows. For each row R1 of T1, each row
d1090 1
a1090 1
			essentially an INNER JOIN ON TRUE.
d1100 11
a1110 10
				<arg choice="req"> <replaceable class="parameter">T1</replaceable> </arg>
				<group choice="opt">
					<arg choice="opt"> INNER </arg>
					<arg>
						<group choice="req">
							<arg choice="plain"> LEFT </arg>
							<arg choice="plain"> RIGHT </arg>
							<arg choice="plain"> FULL </arg>
						</group>
						<arg choice="opt"> OUTER </arg>
d1113 6
a1118 7
				<command> JOIN </command>
				<arg choice="req"> <replaceable class="parameter">T2</replaceable> </arg>
				<group choice="req">
					<arg> ON <replaceable>search condition</replaceable></arg>
					<arg> USING ( <replaceable>join column list</replaceable> ) </arg>
				</group>
				<arg choice="plain"> ... </arg>
d1122 13
a1134 6
			Only the qualified JOIN types can use ON or USING clauses.  The ON clause
			takes a <replaceable>search condition</replaceable>, which is the same
			as in a WHERE clause.  The USING clause takes a comma-separated list of
			column names, which the joined tables must have in common, and joins
			the tables on those columns, resulting in a joined table having one
			column for each common column and all of the other columns from both tables.
d1149 1
a1149 1
				in T2 that satisfies the join specification with R1. 
d1152 1
a1152 1
					<para>
d1154 2
a1155 2
					INNER is the default.  LEFT, RIGHT, and FULL are for
					OUTER JOINs only.
d1171 3
a1173 3
                Then, where a row in T1 does not satisfy the join specification
				with any row in T2, a joined row is returned with null fields in
				columns from T2.
d1192 4
a1195 6
				Rule 1: For each row R2 of T2, the joined table has a row for each
				row in T1 that satisfies the join specification with R2 (transposed
				[INNER] JOIN).
                Rule 2: Where a row in T2 does not satisfy the join specification
				with any row in T1, a joined row is returned with null fields in
				columns from T1.
d1214 7
a1220 2
				First, a LEFT [OUTER] JOIN is performed.
				Then, Rule 2 of a RIGHT [OUTER] JOIN is performed.
a1234 32

		<varlistentry>
		    <term>NATURAL JOINs</term>
    		<listitem>

			<cmdsynopsis>
				<arg choice="req"> <replaceable class="parameter">T1</replaceable> </arg>
				<arg choice="plain"> NATURAL </arg>
				<group choice="opt">
					<arg choice="opt"> INNER </arg>
					<arg>
						<group choice="req">
							<arg choice="plain"> LEFT </arg>
							<arg choice="plain"> RIGHT </arg>
							<arg choice="plain"> FULL </arg>
						</group>
						<arg choice="opt"> OUTER </arg>
      				</arg>
     			</group>
				<command> JOIN </command>				
				<arg choice="req"> <replaceable class="parameter">T2</replaceable> </arg>
			</cmdsynopsis>

			<para>
			A natural join creates a joined table where every pair of matching
			column names between the two tables are merged into one column. The
			join specification is effectively a USING clause containing all the
            common column names and is otherwise like a Qualified JOIN.
			</para>
			</listitem>
		</varlistentry>

d1237 7
d1285 1
a1285 1
	If we want to know how many parts are stored in table PART we use
d1315 1
a1315 1
      group. Thus the aggregate operator is evaluated individually for every
d1530 1
a1530 1
	evaluated for every tuple from the outer query, i.e. the value for
d1588 1
a1588 1
    UNION
d1611 1
a1611 1
    INTERSECT
d1635 1
a1635 1
    EXCEPT
@


1.17
log
@Apply proper sql.sgml change.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.16 2001/01/09 15:48:18 momjian Exp $
d238 2
a239 2
    <parameter>v<subscript>1</subscript></parameter> &isin; 
    <parameter>D<subscript>1</subscript></parameter>,
@


1.16
log
@Attached is a doc patch for doc/src/sgml/sql.sgml.

It adds information about SQL JOIN that is implemented in 7.1.

--
-------- Robert B. Easter
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.15 2000/12/12 05:07:58 tgl Exp $
d1061 14
a1074 4
	 by commas.  A JOIN of two tables is logically like any other
	 table listed in the FROM clause.  A JOINed table can only be JOINed
	 to additional tables in a Qualified JOIN as indicated by the
	 elipses below.
d1094 2
a1095 1
			consisting of all fields in R1 and R2.
d1101 1
a1101 1
		    <term>Qualified JOINs</term>			
d1103 1
d1106 2
a1107 3
				<arg>
					<group>
					<arg choice="plain"> INNER </arg>
d1109 4
a1112 4
						<group>
						<arg> LEFT </arg>
						<arg> RIGHT </arg>
						<arg> FULL </arg>
d1114 1
a1114 1
						<arg> OUTER </arg>
d1116 1
a1116 2
					</group>
     			</arg>
d1119 1
a1119 2
				<arg choice="req">
					<group>
d1122 1
a1122 2
					</group>
				</arg>
a1132 3
			Like all SELECT queries, the <replaceable>select list</replaceable> of the
			SELECT query, before the FROM clause, decides which columns from the joined
			table are in the result	table returned.
d1234 1
d1237 3
a1239 4
				<arg>
					<arg choice="plain"> NATURAL </arg>
					<group>
					<arg choice="plain"> INNER </arg>
d1241 4
a1244 4
						<group>
						<arg> LEFT </arg>
						<arg> RIGHT </arg>
						<arg> FULL </arg>
d1246 1
a1246 1
						<arg> OUTER </arg>
d1248 2
a1249 3
					</group>
     			</arg>
				<command> JOIN </command>
d1257 1
a1257 2
            common column names and is otherwise like a Qualified JOIN except
			additional JOINs to the JOINed table are not permitted.
a1261 4
		<varlistentry>
		    <term>UNION JOIN</term>
		    <listitem><para>Deprecated.</para></listitem>
		</varlistentry>
d1263 1
@


1.15
log
@Revise SELECT reference page for outer joins, subselect in FROM,
ISO-compliant UNION/INTERSECT/EXCEPT.  Revise discussion of rule
rewriter to reflect new subselect-in-FROM implementation of views.
Miscellaneous other cleanups.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.14 2000/12/09 22:59:25 momjian Exp $
d1032 233
@


1.14
log
@Fixes for examples from Thomas Diffenbach
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.13 2000/11/29 20:15:59 petere Exp $
d857 11
a867 11
SELECT [ALL|DISTINCT]
    { * | <replaceable class="parameter">expr_1</replaceable> [AS <replaceable class="parameter">c_alias_1</replaceable>] [, ... 
     [, <replaceable class="parameter">expr_k</replaceable> [AS <replaceable class="parameter">c_alias_k</replaceable>]]]}
    FROM <replaceable class="parameter">table_name_1</replaceable> [<replaceable class="parameter">t_alias_1</replaceable>] 
     [, ... [, <replaceable class="parameter">table_name_n</replaceable> [<replaceable class="parameter">t_alias_n</replaceable>]]]
    [WHERE <replaceable class="parameter">condition</replaceable>]
    [GROUP BY <replaceable class="parameter">name_of_attr_i</replaceable> 
     [,... [, <replaceable class="parameter">name_of_attr_j</replaceable>]] [HAVING <replaceable class="parameter">condition</replaceable>]]
    [{UNION [ALL] | INTERSECT | EXCEPT} SELECT ...]
    [ORDER BY <replaceable class="parameter">name_of_attr_i</replaceable> [ASC|DESC] 
     [, ... [, <replaceable class="parameter">name_of_attr_j</replaceable> [ASC|DESC]]]];
d1040 7
a1046 5
      take the name of an attribute as an argument. The value of the
      aggregate operator is calculated over all values of the specified
      attribute (column) of the whole table. If groups are specified in the
      query the calculation is done only over the values of a group (see next
      section).
d1099 2
a1100 2
      aggregate operators described above can be applied to the groups
      (i.e. the value of the aggregate operator is no longer calculated over
d1103 1
a1103 1
      group.) 
d1184 1
a1184 1
	operator COUNT to every group leading to the total result of the query
d1191 13
a1203 6
      Note that for the result of a query using GROUP BY and aggregate
      operators to make sense the attributes grouped by must also appear in
      the target list. All further attributes not appearing in the GROUP
      BY clause can only be selected by using an aggregate function. On
      the other hand you can not use aggregate functions on attributes
      appearing in the GROUP BY clause.
d1213 8
a1220 5
      HAVING clause. The expressions allowed in the HAVING clause must
      involve aggregate functions. Every expression using only  plain
      attributes belongs to the WHERE clause. On the other hand every
      expression involving an aggregate function must be put to the HAVING
      clause. 
d1295 3
a1297 1
	greater. 
d1316 37
a1352 3
	the WHERE clause of the inner SELECT. As described above the subquery
	is evaluated for every tuple from the outer query i.e. the value for
	S.SNO is always taken from the actual tuple of the outer SELECT. 
d1362 1
a1362 1
      These operations calculate the union, intersect and set theoretic
d1392 1
a1392 1
	Here an example for INTERSECT:
d1412 1
a1412 1
	The only tuple returned by both parts of the query is the one having $SNO=2$.
d1520 1
a1520 1
	 signed packed decimal number of
d1522 1
a1522 1
	 digits precision with assumed
d1524 1
a1524 4
	 of them right to the decimal point.

(15 &ge; <replaceable class="parameter">p</replaceable> &ge; <replaceable class="parameter">q</replaceable> &ge; 0).

d1595 2
a1596 2
	that the only changes a user can percept when an index is present
	are an increased speed.
@


1.13
log
@Rewrite system catalog documentation man page in DocBook with more recent
information.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.12 2000/09/29 20:21:34 petere Exp $
d937 1
a937 1
         (PRICE = 0 OR PRICE < 15);
d1353 1
a1353 1
    WHERE S.SNO > 2;
d1627 1
a1627 1
    WHERE P.PNAME = 'Screw';
@


1.12
log
@Add `id' attributes to all `chapter' and `sect1' tags, to generate useful
names for the HTML files (e.g., not x4856.htm).
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.11 2000/06/20 18:04:18 momjian Exp $
d1577 1
a1577 1
      <xref linkend="catalogs-title" endterm="catalogs-title">). For a
d1786 2
a1787 2
   <sect2 id="catalogs">
    <title id="catalogs-title">System Catalogs</title>
@


1.11
log
@> Great! Please cc: the docs or hackers mailing lists to make sure the
> patches are not lost...

Aggregate doc patches:

The patches are attached. Be great if you could check them over to make
sure all relevant content (and markup) is there...

Isaac Wilcox
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.10 2000/06/14 13:10:48 thomas Exp $
d194 1
a194 1
  <sect1>
d375 1
a375 1
  <sect1>
@


1.10
log
@Fix up typos.
Move "query result" tables to left side of page (remove leading spaces).
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.9 2000/05/02 20:01:52 thomas Exp $
d1035 1
a1035 1
     <title>Aggregate Operators</title>
@


1.9
log
@Fixups in content and markup for 7.0 release.
@
text
@d2 1
a2 1
$Header: /usr/local/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.8 2000/04/07 13:30:58 thomas Exp $
d158 16
a173 14
   SUPPLIER   SNO |  SNAME  |  CITY      SELLS   SNO | PNO
             -----+---------+--------           -----+-----
               1  |  Smith  | London              1  |  1
               2  |  Jones  | Paris               1  |  2
               3  |  Adams  | Vienna              2  |  4
               4  |  Blake  | Rome                3  |  1
                                                  3  |  3
                                                  4  |  2
   PART       PNO |  PNAME  |  PRICE              4  |  3 
             -----+---------+---------            4  |  4
               1  |  Screw  |   10
               2  |  Nut    |    8
               3  |  Bolt   |   15
               4  |  Cam    |   25
d479 1
a479 1
	<classname>R</classname> &cup; <classname>S</classname> is the
d537 6
a542 5
         R   A | B | C      S   C | D | E
            ---+---+---        ---+---+---
             1 | 2 | 3          3 | a | b
             4 | 5 | 6          6 | c | d
             7 | 8 | 9
d553 9
a561 8
       R x S   A | B | R.C | S.C | D | E
              ---+---+-----+-----+---+---
               1 | 2 |  3  |  3  | a | b
               1 | 2 |  3  |  6  | c | d
               4 | 5 |  6  |  3  | a | b
               4 | 5 |  6  |  6  | c | d
               7 | 8 |  9  |  3  | a | b
               7 | 8 |  9  |  6  | c | d
d571 4
a574 4
               A | B | R.C | S.C | D | E
              ---+---+-----+-----+---+---
               1 | 2 |  3  |  3  | a | b
               4 | 5 |  6  |  6  | c | d
d586 4
a589 4
                   A | B | C | D | E
                  ---+---+---+---+---
                   1 | 2 | 3 | a | b
                   4 | 5 | 6 | c | d
d602 3
a604 2
R &divide; S = {t &mid; &forall; t<subscript>s</subscript> &isin; S
	 &exist; t<subscript>r</subscript> &isin; R
d622 9
a630 8
          R   A | B | C | D        S   C | D
             ---+---+---+---          ---+---
              a | b | c | d            c | d
              a | b | e | f            e | f
              b | c | e | f
              e | d | c | d
              e | d | e | f
              a | b | d | e
d637 4
a640 4
                         A | B
                        ---+---
                         a | b
                         e | d
d677 4
a680 4
                             SNAME
                            -------
                             Smith
                             Adams
d729 4
a732 1
      x(A) &mid; F(x)
d745 5
a749 5
<programlisting>
     {x(SNAME) &mid; x &isin; SUPPLIER &and; \nonumber
                       &exist; y &isin; SELLS &exist; z &isin; PART (y(SNO)=x(SNO) &and; \nonumber
                        z(PNO)=y(PNO) &and; \nonumber
                        z(PNAME)='Screw')} \nonumber
d818 3
a820 1
       A &lt; B + 3.
d857 11
a867 11
   SELECT [ALL|DISTINCT] 
          { * | <replaceable class="parameter">expr_1</replaceable> [AS <replaceable class="parameter">c_alias_1</replaceable>] [, ... 
                [, <replaceable class="parameter">expr_k</replaceable> [AS <replaceable class="parameter">c_alias_k</replaceable>]]]}
   FROM <replaceable class="parameter">table_name_1</replaceable> [<replaceable class="parameter">t_alias_1</replaceable>] 
        [, ... [, <replaceable class="parameter">table_name_n</replaceable> [<replaceable class="parameter">t_alias_n</replaceable>]]]
   [WHERE <replaceable class="parameter">condition</replaceable>]
   [GROUP BY <replaceable class="parameter">name_of_attr_i</replaceable> 
             [,... [, <replaceable class="parameter">name_of_attr_j</replaceable>]] [HAVING <replaceable class="parameter">condition</replaceable>]]
   [{UNION [ALL] | INTERSECT | EXCEPT} SELECT ...]
   [ORDER BY <replaceable class="parameter">name_of_attr_i</replaceable> [ASC|DESC] 
             [, ... [, <replaceable class="parameter">name_of_attr_j</replaceable> [ASC|DESC]]]];
d890 2
a891 2
   SELECT * FROM PART
     WHERE PRICE > 10;
d897 4
a900 4
                   PNO |  PNAME  |  PRICE
                  -----+---------+--------
                    3  |  Bolt   |   15
                    4  |  Cam    |   25
d910 3
a912 3
   SELECT PNAME, PRICE 
   FROM PART
   WHERE PRICE > 10;
d934 3
a936 3
   SELECT PNAME, PRICE 
   FROM PART
   WHERE PNAME = 'Bolt' AND
d943 3
a945 3
                      PNAME  |  PRICE
                     --------+--------
                      Bolt   |   15
d955 3
a957 3
   SELECT PNAME, PRICE * 2 AS DOUBLE
   FROM PART
   WHERE PRICE * 2 < 50;
d963 5
a967 5
                      PNAME  |  DOUBLE
                     --------+---------
                      Screw  |    20
                      Nut    |    16
                      Bolt   |    30
d994 4
a997 4
   SELECT S.SNAME, P.PNAME
   FROM SUPPLIER S, PART P, SELLS SE
   WHERE S.SNO = SE.SNO AND
         P.PNO = SE.PNO;
d1003 10
a1012 10
                       SNAME | PNAME
                      -------+-------
                       Smith | Screw
                       Smith | Nut
                       Jones | Cam
                       Adams | Screw
                       Adams | Bolt
                       Blake | Nut
                       Blake | Bolt
                       Blake | Cam
d1054 2
a1055 2
   SELECT AVG(PRICE) AS AVG_PRICE
   FROM PART;
d1063 3
a1065 3
                         AVG_PRICE
                        -----------
                           14.5
d1074 2
a1075 2
   SELECT COUNT(PNO)
   FROM PART;
d1081 3
a1083 3
                           COUNT
                          -------
                             4
d1122 4
a1125 4
   SELECT S.SNO, S.SNAME, COUNT(SE.PNO)
   FROM SUPPLIER S, SELLS SE
   WHERE S.SNO = SE.SNO
   GROUP BY S.SNO, S.SNAME;
d1131 6
a1136 6
                     SNO | SNAME | COUNT
                    -----+-------+-------
                      1  | Smith |   2
                      2  | Jones |   1
                      3  | Adams |   2
                      4  | Blake |   3
d1146 10
a1155 10
                  S.SNO | S.SNAME | SE.PNO
                 -------+---------+--------
                    1   |  Smith  |   1
                    1   |  Smith  |   2
                    2   |  Jones  |   4
                    3   |  Adams  |   1
                    3   |  Adams  |   3
                    4   |  Blake  |   2
                    4   |  Blake  |   3
                    4   |  Blake  |   4
d1164 13
a1176 13
                  S.SNO | S.SNAME | SE.PNO
                 -------+---------+--------
                    1   |  Smith  |   1
                                  |   2
                 --------------------------
                    2   |  Jones  |   4
                 --------------------------
                    3   |  Adams  |   1
                                  |   3
                 --------------------------
                    4   |  Blake  |   2
                                  |   3
                                  |   4
d1218 5
a1222 5
   SELECT S.SNO, S.SNAME, COUNT(SE.PNO)
   FROM SUPPLIER S, SELLS SE
   WHERE S.SNO = SE.SNO
   GROUP BY S.SNO, S.SNAME
   HAVING COUNT(SE.PNO) > 1;
d1228 5
a1232 5
                     SNO | SNAME | COUNT
                    -----+-------+-------
                      1  | Smith |   2
                      3  | Adams |   2
                      4  | Blake |   3
d1257 4
a1260 4
   SELECT * 
   FROM PART 
   WHERE PRICE > (SELECT PRICE FROM PART
                  WHERE PNAME='Screw');
d1268 4
a1271 4
                   PNO |  PNAME  |  PRICE
                  -----+---------+--------
                    3  |  Bolt   |   15
                    4  |  Cam    |   25
d1286 1
a1286 1
<para>
d1291 5
a1295 5
   SELECT * 
   FROM SUPPLIER S
   WHERE NOT EXISTS
             (SELECT * FROM SELLS SE
              WHERE SE.SNO = S.SNO);
d1324 7
a1330 7
   SELECT S.SNO, S.SNAME, S.CITY
   FROM SUPPLIER S
   WHERE S.SNAME = 'Jones'
   UNION
   SELECT S.SNO, S.SNAME, S.CITY
   FROM SUPPLIER S
   WHERE S.SNAME = 'Adams';    
d1336 4
a1339 4
                     SNO | SNAME |  CITY
                    -----+-------+--------
                      2  | Jones | Paris
                      3  | Adams | Vienna
d1347 7
a1353 7
   SELECT S.SNO, S.SNAME, S.CITY
   FROM SUPPLIER S
   WHERE S.SNO > 1
   INTERSECT
   SELECT S.SNO, S.SNAME, S.CITY
   FROM SUPPLIER S
   WHERE S.SNO > 2;
d1359 3
a1361 4
                     SNO | SNAME |  CITY
                    -----+-------+--------
                      2  | Jones | Paris
The only tuple returned by both parts of the query is the one having $SNO=2$.
d1363 2
d1371 7
a1377 7
   SELECT S.SNO, S.SNAME, S.CITY
   FROM SUPPLIER S
   WHERE S.SNO > 1
   EXCEPT
   SELECT S.SNO, S.SNAME, S.CITY
   FROM SUPPLIER S
   WHERE S.SNO > 3;
d1383 4
a1386 4
                     SNO | SNAME |  CITY
                    -----+-------+--------
                      2  | Jones | Paris
                      3  | Adams | Vienna
d1410 5
a1414 5
	<synopsis>
   CREATE TABLE <replaceable class="parameter">table_name</replaceable>
                (<replaceable class="parameter">name_of_attr_1</replaceable> <replaceable class="parameter">type_of_attr_1</replaceable>
                 [, <replaceable class="parameter">name_of_attr_2</replaceable> <replaceable class="parameter">type_of_attr_2</replaceable> 
                 [, ...]]);
d1426 5
a1430 5
   CREATE TABLE SUPPLIER
                (SNO   INTEGER,
                 SNAME VARCHAR(20),
                 CITY  VARCHAR(20));
	</programlisting>
d1432 6
a1437 6
	<programlisting>
   CREATE TABLE PART
                (PNO   INTEGER,
                 PNAME VARCHAR(20),
                 PRICE DECIMAL(4 , 2));
	</programlisting>
d1439 4
a1442 4
	<programlisting>
   CREATE TABLE SELLS
                (SNO INTEGER,
                 PNO INTEGER);
d1478 1
a1478 1
(15 &ge; <replaceable class="parameter">p</replaceable> &ge; <replaceable class="parameter">q</replaceable>q &ge; 0).
d1529 2
a1530 2
   CREATE INDEX <replaceable class="parameter">index_name</replaceable> 
   ON <replaceable class="parameter">table_name</replaceable> ( <replaceable class="parameter">name_of_attribute</replaceable> );
d1543 1
a1543 2
   CREATE INDEX I
   ON SUPPLIER (SNAME);
d1592 2
a1593 2
   CREATE VIEW <replaceable class="parameter">view_name</replaceable>
   AS <replaceable class="parameter">select_stmt</replaceable>
d1611 6
a1616 6
   CREATE VIEW London_Suppliers
      AS SELECT S.SNAME, P.PNAME
         FROM SUPPLIER S, PART P, SELLS SE
         WHERE S.SNO = SE.SNO AND
               P.PNO = SE.PNO AND
               S.CITY = 'London';
d1626 2
a1627 3
   SELECT *
   FROM London_Suppliers
   WHERE P.PNAME = 'Screw';
d1633 3
a1635 3
                       SNAME | PNAME
                      -------+-------
                       Smith | Screw                 
d1659 1
a1659 1
   DROP TABLE <replaceable class="parameter">table_name</replaceable>;
d1667 1
a1667 1
   DROP TABLE SUPPLIER;
d1675 1
a1675 1
   DROP INDEX <replaceable class="parameter">index_name</replaceable>;
d1683 1
a1683 1
   DROP VIEW <replaceable class="parameter">view_name</replaceable>;
d1702 3
a1704 4
   INSERT INTO <replaceable class="parameter">table_name</replaceable> (<replaceable class="parameter">name_of_attr_1</replaceable> 
                             [, <replaceable class="parameter">name_of_attr_2</replaceable> [,...]])
   VALUES (<replaceable class="parameter">val_attr_1</replaceable> 
           [, <replaceable class="parameter">val_attr_2</replaceable> [, ...]]);
d1714 2
a1715 2
   INSERT INTO SUPPLIER (SNO, SNAME, CITY)
   VALUES (1, 'Smith', 'London');
d1723 2
a1724 2
   INSERT INTO SELLS (SNO, PNO)
   VALUES (1, 1);
d1737 4
a1740 4
   UPDATE <replaceable class="parameter">table_name</replaceable>
   SET <replaceable class="parameter">name_of_attr_1</replaceable> = <replaceable class="parameter">value_1</replaceable> 
       [, ... [, <replaceable class="parameter">name_of_attr_k</replaceable> = <replaceable class="parameter">value_k</replaceable>]]
   WHERE <replaceable class="parameter">condition</replaceable>;
d1749 3
a1751 3
   UPDATE PART
   SET PRICE = 15
   WHERE PNAME = 'Screw';
d1769 2
a1770 2
   DELETE FROM <replaceable class="parameter">table_name</replaceable>
   WHERE <replaceable class="parameter">condition</replaceable>;
d1779 2
a1780 2
   DELETE FROM SUPPLIER
   WHERE SNAME = 'Smith';
@


1.9.2.1
log
@Fix markup to allow doc building.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.9 2000/05/02 20:01:52 thomas Exp $
d158 14
a171 16
SUPPLIER:                   SELLS:
 SNO |  SNAME  |  CITY       SNO | PNO
----+---------+--------     -----+-----
 1  |  Smith  | London        1  |  1
 2  |  Jones  | Paris         1  |  2
 3  |  Adams  | Vienna        2  |  4
 4  |  Blake  | Rome          3  |  1
                              3  |  3
                              4  |  2
PART:                         4  |  3
 PNO |  PNAME  |  PRICE       4  |  4
----+---------+---------
 1  |  Screw  |   10
 2  |  Nut    |    8
 3  |  Bolt   |   15
 4  |  Cam    |   25
d477 1
a477 1
	<classname>R</classname> &cap; <classname>S</classname> is the
d535 5
a539 6
R:                 S:
 A | B | C          C | D | E
---+---+---        ---+---+---
 1 | 2 | 3          3 | a | b
 4 | 5 | 6          6 | c | d
 7 | 8 | 9
d550 8
a557 9
R x S:
 A | B | R.C | S.C | D | E
---+---+-----+-----+---+---
 1 | 2 |  3  |  3  | a | b
 1 | 2 |  3  |  6  | c | d
 4 | 5 |  6  |  3  | a | b
 4 | 5 |  6  |  6  | c | d
 7 | 8 |  9  |  3  | a | b
 7 | 8 |  9  |  6  | c | d
d567 4
a570 4
 A | B | R.C | S.C | D | E
---+---+-----+-----+---+---
 1 | 2 |  3  |  3  | a | b
 4 | 5 |  6  |  6  | c | d
d582 4
a585 4
 A | B | C | D | E
---+---+---+---+---
 1 | 2 | 3 | a | b
 4 | 5 | 6 | c | d
d598 2
a599 3
	<programlisting>
R &divide; S = {t &mid; &forall; t<subscript>s</subscript> &isin; S &exist; t<subscript>r</subscript> &isin; R
	</programlisting>
d617 8
a624 9
R:                    S:
 A | B | C | D         C | D
---+---+---+---       ---+---
 a | b | c | d         c | d
 a | b | e | f         e | f
 b | c | e | f
 e | d | c | d
 e | d | e | f
 a | b | d | e
d631 4
a634 4
 A | B
---+---
 a | b
 e | d
d671 4
a674 4
 SNAME
-------
 Smith
 Adams
d723 1
a723 4

     <programlisting>
x(A) &mid; F(x)
     </programlisting>
d736 5
a740 5
     <programlisting>
{x(SNAME) &mid; x &isin; SUPPLIER &and;
    &exist; y &isin; SELLS &exist; z &isin; PART (y(SNO)=x(SNO) &and;
    z(PNO)=y(PNO) &and;
    z(PNAME)='Screw')}
d809 1
a809 3
       <programlisting>
A &lt; B + 3.
       </programlisting>
d846 11
a856 11
SELECT [ALL|DISTINCT]
    { * | <replaceable class="parameter">expr_1</replaceable> [AS <replaceable class="parameter">c_alias_1</replaceable>] [, ... 
     [, <replaceable class="parameter">expr_k</replaceable> [AS <replaceable class="parameter">c_alias_k</replaceable>]]]}
    FROM <replaceable class="parameter">table_name_1</replaceable> [<replaceable class="parameter">t_alias_1</replaceable>] 
     [, ... [, <replaceable class="parameter">table_name_n</replaceable> [<replaceable class="parameter">t_alias_n</replaceable>]]]
    [WHERE <replaceable class="parameter">condition</replaceable>]
    [GROUP BY <replaceable class="parameter">name_of_attr_i</replaceable> 
     [,... [, <replaceable class="parameter">name_of_attr_j</replaceable>]] [HAVING <replaceable class="parameter">condition</replaceable>]]
    [{UNION [ALL] | INTERSECT | EXCEPT} SELECT ...]
    [ORDER BY <replaceable class="parameter">name_of_attr_i</replaceable> [ASC|DESC] 
     [, ... [, <replaceable class="parameter">name_of_attr_j</replaceable> [ASC|DESC]]]];
d879 2
a880 2
SELECT * FROM PART
    WHERE PRICE > 10;
d886 4
a889 4
 PNO |  PNAME  |  PRICE
-----+---------+--------
  3  |  Bolt   |   15
  4  |  Cam    |   25
d899 3
a901 3
SELECT PNAME, PRICE 
    FROM PART
    WHERE PRICE > 10;
d923 3
a925 3
SELECT PNAME, PRICE 
    FROM PART
    WHERE PNAME = 'Bolt' AND
d932 3
a934 3
 PNAME  |  PRICE
--------+--------
 Bolt   |   15
d944 3
a946 3
SELECT PNAME, PRICE * 2 AS DOUBLE
    FROM PART
    WHERE PRICE * 2 < 50;
d952 5
a956 5
 PNAME  |  DOUBLE
--------+---------
 Screw  |    20
 Nut    |    16
 Bolt   |    30
d983 4
a986 4
SELECT S.SNAME, P.PNAME
    FROM SUPPLIER S, PART P, SELLS SE
    WHERE S.SNO = SE.SNO AND
          P.PNO = SE.PNO;
d992 10
a1001 10
 SNAME | PNAME
-------+-------
 Smith | Screw
 Smith | Nut
 Jones | Cam
 Adams | Screw
 Adams | Bolt
 Blake | Nut
 Blake | Bolt
 Blake | Cam
d1043 2
a1044 2
SELECT AVG(PRICE) AS AVG_PRICE
    FROM PART;
d1052 3
a1054 3
 AVG_PRICE
-----------
   14.5
d1063 2
a1064 2
SELECT COUNT(PNO)
    FROM PART;
d1070 3
a1072 3
 COUNT
-------
   4
d1111 4
a1114 4
SELECT S.SNO, S.SNAME, COUNT(SE.PNO)
    FROM SUPPLIER S, SELLS SE
    WHERE S.SNO = SE.SNO
    GROUP BY S.SNO, S.SNAME;
d1120 6
a1125 6
 SNO | SNAME | COUNT
-----+-------+-------
  1  | Smith |   2
  2  | Jones |   1
  3  | Adams |   2
  4  | Blake |   3
d1135 10
a1144 10
 S.SNO | S.SNAME | SE.PNO
-------+---------+--------
   1   |  Smith  |   1
   1   |  Smith  |   2
   2   |  Jones  |   4
   3   |  Adams  |   1
   3   |  Adams  |   3
   4   |  Blake  |   2
   4   |  Blake  |   3
   4   |  Blake  |   4
d1153 13
a1165 13
 S.SNO | S.SNAME | SE.PNO
-------+---------+--------
   1   |  Smith  |   1
                 |   2
--------------------------
   2   |  Jones  |   4
--------------------------
   3   |  Adams  |   1
                 |   3
--------------------------
   4   |  Blake  |   2
                 |   3
                 |   4
d1207 5
a1211 5
SELECT S.SNO, S.SNAME, COUNT(SE.PNO)
    FROM SUPPLIER S, SELLS SE
    WHERE S.SNO = SE.SNO
    GROUP BY S.SNO, S.SNAME
    HAVING COUNT(SE.PNO) > 1;
d1217 5
a1221 5
 SNO | SNAME | COUNT
-----+-------+-------
  1  | Smith |   2
  3  | Adams |   2
  4  | Blake |   3
d1246 4
a1249 4
SELECT * 
    FROM PART 
    WHERE PRICE > (SELECT PRICE FROM PART
                   WHERE PNAME='Screw');
d1257 4
a1260 4
 PNO |  PNAME  |  PRICE
-----+---------+--------
  3  |  Bolt   |   15
  4  |  Cam    |   25
d1275 1
a1275 1
       <para>
d1280 5
a1284 5
SELECT * 
    FROM SUPPLIER S
    WHERE NOT EXISTS
        (SELECT * FROM SELLS SE
         WHERE SE.SNO = S.SNO);
d1313 7
a1319 7
SELECT S.SNO, S.SNAME, S.CITY
    FROM SUPPLIER S
    WHERE S.SNAME = 'Jones'
    UNION
    SELECT S.SNO, S.SNAME, S.CITY
    FROM SUPPLIER S
    WHERE S.SNAME = 'Adams';    
d1325 4
a1328 4
 SNO | SNAME |  CITY
-----+-------+--------
  2  | Jones | Paris
  3  | Adams | Vienna
d1336 7
a1342 7
SELECT S.SNO, S.SNAME, S.CITY
    FROM SUPPLIER S
    WHERE S.SNO > 1
    INTERSECT
    SELECT S.SNO, S.SNAME, S.CITY
    FROM SUPPLIER S
    WHERE S.SNO > 2;
d1348 4
a1351 3
 SNO | SNAME |  CITY
-----+-------+--------
  2  | Jones | Paris
a1352 2

	The only tuple returned by both parts of the query is the one having $SNO=2$.
d1359 7
a1365 7
SELECT S.SNO, S.SNAME, S.CITY
    FROM SUPPLIER S
    WHERE S.SNO > 1
    EXCEPT
    SELECT S.SNO, S.SNAME, S.CITY
    FROM SUPPLIER S
    WHERE S.SNO > 3;
d1371 4
a1374 4
 SNO | SNAME |  CITY
-----+-------+--------
  2  | Jones | Paris
  3  | Adams | Vienna
d1398 5
a1402 5
      <synopsis>
CREATE TABLE <replaceable class="parameter">table_name</replaceable>
    (<replaceable class="parameter">name_of_attr_1</replaceable> <replaceable class="parameter">type_of_attr_1</replaceable>
     [, <replaceable class="parameter">name_of_attr_2</replaceable> <replaceable class="parameter">type_of_attr_2</replaceable> 
     [, ...]]);
d1414 5
a1418 5
CREATE TABLE SUPPLIER
    (SNO   INTEGER,
     SNAME VARCHAR(20),
     CITY  VARCHAR(20));
     </programlisting>
d1420 6
a1425 6
     <programlisting>
CREATE TABLE PART
    (PNO   INTEGER,
     PNAME VARCHAR(20),
     PRICE DECIMAL(4 , 2));
     </programlisting>
d1427 4
a1430 4
     <programlisting>
CREATE TABLE SELLS
    (SNO INTEGER,
     PNO INTEGER);
d1466 1
a1466 1
(15 &ge; <replaceable class="parameter">p</replaceable> &ge; <replaceable class="parameter">q</replaceable> &ge; 0).
d1517 2
a1518 2
CREATE INDEX <replaceable class="parameter">index_name</replaceable> 
    ON <replaceable class="parameter">table_name</replaceable> ( <replaceable class="parameter">name_of_attribute</replaceable> );
d1531 2
a1532 1
CREATE INDEX I ON SUPPLIER (SNAME);
d1581 2
a1582 2
CREATE VIEW <replaceable class="parameter">view_name</replaceable>
    AS <replaceable class="parameter">select_stmt</replaceable>
d1600 6
a1605 6
CREATE VIEW London_Suppliers
    AS SELECT S.SNAME, P.PNAME
        FROM SUPPLIER S, PART P, SELLS SE
        WHERE S.SNO = SE.SNO AND
              P.PNO = SE.PNO AND
              S.CITY = 'London';
d1615 3
a1617 2
SELECT * FROM London_Suppliers
    WHERE P.PNAME = 'Screw';
d1623 3
a1625 3
 SNAME | PNAME
-------+-------
 Smith | Screw                 
d1649 1
a1649 1
DROP TABLE <replaceable class="parameter">table_name</replaceable>;
d1657 1
a1657 1
DROP TABLE SUPPLIER;
d1665 1
a1665 1
DROP INDEX <replaceable class="parameter">index_name</replaceable>;
d1673 1
a1673 1
DROP VIEW <replaceable class="parameter">view_name</replaceable>;
d1692 4
a1695 3
INSERT INTO <replaceable class="parameter">table_name</replaceable> (<replaceable class="parameter">name_of_attr_1</replaceable> 
    [, <replaceable class="parameter">name_of_attr_2</replaceable> [,...]])
    VALUES (<replaceable class="parameter">val_attr_1</replaceable> [, <replaceable class="parameter">val_attr_2</replaceable> [, ...]]);
d1705 2
a1706 2
INSERT INTO SUPPLIER (SNO, SNAME, CITY)
    VALUES (1, 'Smith', 'London');
d1714 2
a1715 2
INSERT INTO SELLS (SNO, PNO)
    VALUES (1, 1);
d1728 4
a1731 4
UPDATE <replaceable class="parameter">table_name</replaceable>
    SET <replaceable class="parameter">name_of_attr_1</replaceable> = <replaceable class="parameter">value_1</replaceable> 
        [, ... [, <replaceable class="parameter">name_of_attr_k</replaceable> = <replaceable class="parameter">value_k</replaceable>]]
    WHERE <replaceable class="parameter">condition</replaceable>;
d1740 3
a1742 3
UPDATE PART
    SET PRICE = 15
    WHERE PNAME = 'Screw';
d1760 2
a1761 2
DELETE FROM <replaceable class="parameter">table_name</replaceable>
    WHERE <replaceable class="parameter">condition</replaceable>;
d1770 2
a1771 2
DELETE FROM SUPPLIER
    WHERE SNAME = 'Smith';
@


1.8
log
@Fix path to initdb in installation instructions.
General cleanup for 7.0.
@
text
@d2 1
a2 1
$Header: /usr/local/cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.7 2000/03/31 03:27:41 thomas Exp $
d27 1
a27 1
   The name <quote><acronym>SQL</acronym></quote> is an abbreviation for
d762 2
a763 2
     1972. This proof is based on an algorithm (<quote>Codd's reduction
     algorithm</quote>) by which an arbitrary expression of the relational
@


1.7
log
@Minor markup changes. Refer to (".../catalog") in the emacs hints.
@
text
@d2 1
a2 1
$Header$
d10 9
a18 1
    This chapter originally appeared as a part of
d25 2
a26 1
   <acronym>SQL</acronym> has become the most popular relational query language.
d30 2
a31 1
   language SEQUEL (<firstterm>Structured English Query Language</firstterm>) at IBM
d41 2
a42 1
   implemented a large subset of SEQUEL/2 (now <acronym>SQL</acronym>) and a number of
d48 2
a49 1
   implemented the <acronym>SQL</acronym> language based on the System R technology.
d63 4
a66 2
   <acronym>SQL</acronym> is also an official standard now. In 1982 the American National
   Standards Institute (<acronym>ANSI</acronym>) chartered its Database Committee X3H2 to
d73 4
a76 2
   This original standard version of <acronym>SQL</acronym> is often referred to,
   informally, as "<abbrev>SQL/86</abbrev>". In 1989 the original standard was extended
d92 2
a93 1
   normally meant when people refer to "the <acronym>SQL</acronym> standard". A detailed
d98 2
a99 1
   is under development. It is planned to make <acronym>SQL</acronym> a Turing-complete
d121 4
a124 2
    A <firstterm>relational database</firstterm> is a database that is perceived by its
    users as a <firstterm>collection of tables</firstterm> (and nothing else but tables).
d177 4
a180 2
    The tables PART and SUPPLIER may be regarded as <firstterm>entities</firstterm> and
    SELLS may be regarded as a <firstterm>relationship</firstterm> between a particular
d185 2
a186 1
    As we will see later, <acronym>SQL</acronym> operates on tables like the ones just
d197 2
a198 1
    set-theoretic <firstterm>relation</firstterm> which is a subset of the Cartesian
d211 2
a212 1
The <firstterm>Cartesian product</firstterm> of domains $D_{1}, D_{2},\ldots, D_{k}$ written
d332 4
a335 2
       whereas a <firstterm>relation</firstterm> is an instance of a <firstterm>relation
       scheme</firstterm>. The relation consists of tuples (and can therefore be
d362 4
a365 2
     <type>INTEGER</type>. With the assignment of a data type we also have selected
     a domain for an attribute. The domain of <classname>SNAME</classname> is the set of all
d377 2
a378 1
    In the previous section (<xref linkend="formal-notion" endterm="formal-notion">)
d390 2
a391 1
       The <firstterm>Relational Algebra</firstterm> which is an algebraic notation,
d399 2
a400 1
       The <firstterm>Relational Calculus</firstterm> which is a logical notation,
d418 2
a419 1
	SELECT (&sigma;): extracts <firstterm>tuples</firstterm> from a relation that
d477 2
a478 1
	<classname>R</classname> &cup; <classname>S</classname> is the set of tuples
d481 2
a482 1
	We again require that <classname>R</classname> and <classname>S</classname> have the
d493 2
a494 1
	is the set of tuples in <classname>R</classname> but not in <classname>S</classname>.
d711 1
a711 1
     [<xref linkend="DATE94" endterm="DATE94">]
d713 1
a713 1
     [<xref linkend="ULL88" endterm="ULL88">].
d766 1
a766 1
     [<xref linkend="DATE94" endterm="DATE94">]
d768 1
a768 1
     [<xref linkend="ULL88" endterm="ULL88">].
d789 2
a790 1
    algebra) can also be formulated using <acronym>SQL</acronym>. There are, however,
d792 2
a793 1
    is a list of some additional features provided by <acronym>SQL</acronym> that are not
d805 2
a806 1
       Arithmetic capability: In <acronym>SQL</acronym> it is possible to involve
d829 2
a830 1
       <firstterm>max</firstterm>, etc. can be applied to columns of a relation to
d961 2
a962 1
	target list to assign a new title to the resulting column. This new title
d1552 4
a1555 2
      does not <emphasis>physically</emphasis> exist in the database but looks to the user
      as if it does. By contrast, when we talk of a <firstterm>base table</firstterm> there is
d1596 2
a1597 1
      the tables from <xref linkend="supplier-fig" endterm="supplier-fig"> again):
d1634 2
a1635 1
      those base tables. After that the additional qualifications (given in the
d1794 1
d1796 1
a1796 1
     <citetitle>SIM98</citetitle>
d1799 1
a1799 1
     <citetitle>DATE</citetitle>.
d1864 2
a1865 2
     [<xref linkend="DATE97" endterm="DATE97">],
     [<xref linkend="DATE94" endterm="DATE94">],
d1867 1
a1867 1
     [<xref linkend="ULL88" endterm="ULL88">].
@


1.6
log
@Add chapters on CVS access, MVCC, SQL theory to the docs.
Add an appendix with more details on date/time attributes and handling.
Update most references to Postgres version numbers to 6.5,
 *except* for the porting list which will require a report
 from a successful installation to be updated.
@
text
@d1 4
d1829 1
a1829 1
mode: sgml
d1839 1
a1839 1
sgml-local-catalogs:"/usr/lib/sgml/catalog"
@


1.5
log
@Finish initial markup of cvs.sgml, and include it in the programmer's guide
 and the integrated doc. Clean up other markup.
@
text
@d91 3
a93 3
    1970. We will give a formal description of the relational model in
    section <xref linkend="formal-notion" endterm="formal-notion">
    <!--{\it Formal Notion of the Relational Data Model}-->
d104 1
a104 1
    Figure <xref linkend="supplier-fig" endterm="supplier-fig">
d130 1
d166 1
a166 1
   <title id="formal-notion">Formal Notion of the Relational Data Model</title>
d292 1
a292 1
    1 &lt;&equals; <literal>i</literal> &lt;&equals; <literal>k</literal>,
d329 1
a329 1
     for character strings of length &lt;&equals; 20),
d333 1
a333 1
     character strings of length &lt;&equals; 20,
d341 1
a341 2
   <title id="operations">Operations in the Relational Data
    Model</title>
d344 1
a344 1
    In <xref linkend="formal-notion" endterm="formal-notion">
d486 2
a487 2
       <example id="join-example">
	<title>An Inner Join</title>
d603 2
a604 2
     algebra refer to <citetitle>ullman</citetitle> or
     <citetitle>date86</citetitle>.
d607 11
a617 8
    <para id="suppl-rel-alg">
     Recall that we formulated all those relational operators to be able to
     retrieve data from the database. Let's return to our example of
     section <xref linkend="operations" endterm="operations">
     where someone wanted to know the names of all
     suppliers that sell the part <literal>Screw</literal>. 
     This question can be answered
     using relational algebra by the following operation:
d619 4
a622 1
      &pi;<subscript>SUPPLIER.SNAME</subscript>(&sigma;<subscript>PART.PNAME='Screw'</subscript>(SUPPLIER &prod; SELLS &prod; PART))
d624 5
a628 1
    </para>
d630 1
a630 7
    <para>
     We call such an operation a query. If we evaluate the above query
     against the tables from figure
     <xref linkend="supplier-fig" endterm="supplier-fig"> (The suppliers and
     parts database) we will obtain the following result:

     <programlisting>
d635 3
a637 2
     </programlisting>
    </para>
d670 4
a673 2
     <acronym>TRC</acronym>) see <citetitle>date86</citetitle> or
     <citetitle>ullman</citetitle>.
d696 1
d701 1
d705 1
a705 1
     Evaluating the query against the tables from figure
a706 1
     (The suppliers and parts database)
d708 1
a708 1
     as in example
d726 3
a728 2
     <citetitle>date86</citetitle> and
     <citetitle>ullman</citetitle>. 
d745 2
a746 1
    As most modern relational languages <acronym>SQL</acronym> is based on the tuple
d794 1
a794 1
    <title>Select</title>
d819 1
a819 1
     figure <xref linkend="supplier-fig" endterm="supplier-fig"> (The suppliers and parts database).
d829 1
a829 1
       <title>Simple Query with Qualification</title>
d871 1
a871 2
	(see section <xref linkend="rel-alg" endterm="rel-alg">
	(Relational Algebra).
d965 1
a965 1
      a dot. The join is calculated in the same way as shown in example
d991 1
a991 1
       <title>Aggregates</title>
d1060 1
a1060 1
       <title>Aggregates</title>
d1155 1
a1155 1
       <title>Having</title>
d1194 1
a1194 1
       <title>Subselect</title>
d1262 1
a1262 1
       <title>Union, Intersect, Except</title>
d1346 1
a1346 1
     <title>Create Table</title>
d1361 1
a1361 1
       <title>Table Creation</title>
d1364 1
a1364 1
	To create the tables defined in figure
d1479 1
a1479 1
       <title>Create Index</title>
d1518 2
a1519 1
      catalogs (see section <xref linkend="catalogs" endterm="catalogs">). For a
d1540 1
a1540 1
      in section <xref linkend="select" endterm="select">.
d1549 1
a1549 1
      the tables from figure <xref linkend="supplier-fig" endterm="supplier-fig"> again):
d1638 1
a1638 1
      <xref linkend="create" endterm="create">), it can be filled
d1651 2
a1652 2
      To insert the first tuple into the relation SUPPLIER of figure
      <xref linkend="supplier-fig" endterm="supplier-fig"> we use the
d1729 1
a1729 1
    <title>System Catalogs</title>
d1785 9
a1793 4
     A program using embedded <acronym>SQL</acronym> in a host language consists of statements
     of the host language and of embedded <acronym>SQL</acronym> (ESQL) statements. Every ESQL
     statement begins with the keywords EXEC SQL. The ESQL statements are
     transformed to statements of the host language by a <firstterm>precompiler</firstterm>
d1800 2
a1801 2
     When we look at the examples throughout section
     <xref linkend="select" endterm="select"> we
d1813 5
a1817 2
     refer to <citetitle>date</citetitle>,
     <citetitle>date86</citetitle> or <citetitle>ullman</citetitle>.
@


1.4
log
@Rearrange and consolidate the Admin Guide.
Add reference pages for utilities and remove standalone chapters for same.
Add material for an appendix on date/time properties, but not yet
 integrated with the User's Guide.
Break up the former chapter on pg_options
 into Admin and Programmer's Guides.
@
text
@d291 1
a291 1
    1 &lt;&equal; <literal>i</literal> &lt;&equal; <literal>k</literal>,
d328 1
a328 1
     for character strings of length &lt;&equal; 20),
d332 1
a332 1
     character strings of length &lt;&equal; 20,
@


1.3
log
@First version of markup which can run through jade for html.
Probably not acceptable yet. Need to check some math symbols and markup.
@
text
@d291 1
a291 1
    1 &le; <literal>i</literal> &le; <literal>k</literal>,
d328 2
a329 1
     for character strings of length &le; 20), the type of <classname>SNO</classname> will be
d332 2
a333 1
     character strings of length &le; 20, the domain of <classname>SNO</classname> is the set of
d344 1
a344 1
    In section <xref linkend="formal-notion" endterm="formal-notion">
d486 2
a487 4
       <para id="join-example">
	Let's have a look at the tables that are produced by evaluating the steps
	necessary for a join.
	Let the following two tables be given:
d489 6
a494 1
	<programlisting>
d500 3
a502 2
	</programlisting>
       </para>
@


1.2
log
@Add EXCEPT/INTERSECT doc changes.
@
text
@d6 4
a9 22
    This chapter originally appeared as a part of 
    Stefan Simkovics' Master's Thesis.

<!-- Move this info to the bibliography
\title{{\Large Master's Thesis}\\
\vspace{1cm}
Enhancement of the ANSI SQL Implementation of PostgreSQL\\[1em]
{\normalsize written by\\[1em]}
{\large Stefan Simkovics\\
Paul Petersgasse 36\\
2384 Breitenfurt\\ 
AUSTRIA \\
ssimkovi@@ag.or.at\\[1em]}
{\normalsize at \\[1em]}
{\large Department of Information Systems\\
Vienna University of Technology\\[1em]}
{\normalsize with support by\\[1em]}
{\large O.Univ.Prof.Dr. Georg Gottlob\\} 
{\normalsize and\\}
{\large Univ.Ass. Mag. Katrin Seyr\\}}
-->
    </para>
d13 2
a14 3
   SQL has become one of the most popular relational query languages all
   over the world. 
   The name "<literal>SQL</literal>" is an abbreviation for
d20 2
a21 1
   of SEQUEL called SEQUEL/2 was defined and the name was changed to SQL
d26 8
a33 7
A new prototype called System R was developed by IBM in 1977. System R
implemented a large subset of SEQUEL/2 (now SQL) and a number of
changes were made to SQL during the project. System R was installed in
a number of user sites, both internal IBM sites and also some selected
customer sites. Thanks to the success and acceptance of System R at
those user sites IBM started to develop commercial products that
implemented the SQL language based on the System R technology.
d37 7
a43 3
Over the next years IBM and also a number of other vendors announced
SQL products such as SQL/DS (IBM), DB2 (IBM) ORACLE (Oracle Corp.)
DG/SQL (Data General Corp.)  SYBASE (Sybase Inc.).
d47 14
a60 11
SQL is also an official standard now. In 1982 the American National
Standards Institute (ANSI) chartered its Database Committee X3H2 to
develop a proposal for a standard relational language. This proposal
was ratified in 1986 and consisted essentially of the IBM dialect of
SQL. In 1987 this ANSI standard was also accepted as an international
standard by the International Organization for Standardization
(ISO). This original standard version of SQL is often referred to,
informally, as "SQL/86". In 1989 the original standard was extended
and this new standard is often, again informally, referred to as
"SQL/89". Also in 1989, a related standard called {\it Database
Language Embedded SQL} was developed.
d64 2
a65 1
   The ISO and ANSI committees have been working for many years on the
d67 12
a78 8
   referred to informally as "SQL2" or "SQL/92". This version became a
   ratified standard - "International Standard \mbox{ISO/IEC 9075:1992}, {\it
   Database Language SQL}" - in late 1992. "SQL/92" is the version
   normally meant when people refer to "the SQL standard". A detailed
   description of "SQL/92" is given in \cite{date}. At the time of
   writing this document a new standard informally referred to as "SQL3"
   is under development. It is planned to make SQL a turing-complete
   language, i.e.\ all computable queries (e.g. recursive queries) will be
d84 1
a84 1
   <title>The Relational Data Model}</title>
d87 4
a90 2
    As mentioned before, SQL is a relational language. That means it is
    based on the "relational data model" first published by E.F. Codd in
d92 1
a92 1
    section <xref id="formal-notion">
d99 2
a100 2
    A {\it relational database} is a database that is perceived by its
    users as a {\it collection of tables} (and nothing else but tables).
d103 30
a132 14
    contained in the table. Figure \ref{supplier} shows an example of a
    database consisting of three tables:
\begin{itemize}
\item SUPPLIER is a table storing the number
(SNO), the name (SNAME) and the city (CITY) of a supplier.
\item PART is a table storing the number (PNO) the name (PNAME) and
the price (PRICE) of a part.
\item SELLS stores information about which part (PNO) is sold by which
supplier (SNO). It serves in a sense to connect the other two tables
together.
\end{itemize}
%
\begin{figure}[h]
\begin{verbatim}
d147 34
a180 23
\end{verbatim}
\caption{The suppliers and parts database}
\label{supplier}
\end{figure}
%
The tables PART and SUPPLIER may be regarded as {\it entities} and
SELLS may be regarded as a {\it relationship} between a particular
part and a particular supplier. 

As we will see later, SQL operates on tables like the ones just
defined but before that we will study the theory of the relational
model.

\subsection{Formal Notion of the Relational Data Model}
\label{formal_notion}
The mathematical concept underlying the relational model is the
set-theoretic {\it relation} which is a subset of the Cartesian
product of a list of domains. This set-theoretic {\it relation} gives
the model its name (do not confuse it with the relationship from the {\it
Entity-Relationship model}). Formally a domain is simply a set of
values. For example the set of integers is a domain. Also the set of
character strings of length 20 and the real numbers are examples of
domains.
d182 1
a182 1
The {\it Cartesian} product of domains $D_{1}, D_{2},\ldots, D_{k}$ written
d185 1
a185 1
D_{1}, v_{2} \in D_{2}, \ldots, v_{k} \in D_{k}$}.  
d187 30
a216 1
For example, when we have $k=2$, $D_{1}=\{0,1\}$ and
d219 11
a229 1
%
d234 39
a272 13
%
For example $\{(0,a),(0,b),(1,a)\}$ is a relation, it is in fact a
subset of $D_{1} \times D_{2}$ mentioned above.
The members of a relation are called tuples. Each relation of some
Cartesian product \mbox{$D_{1} \times D_{2} \times \ldots \times
D_{k}$} is said to have arity $k$ and is therefore a set of $k$-tuples.

A relation can be viewed as a table (as we already did, remember
figure \ref{supplier} {\it The suppliers and parts database}) where
every tuple is represented by a row and every column corresponds to
one component of a tuple. Giving names (called attributes) to the
columns leads to the definition of a {\it relation scheme}.
%
d280 211
a490 88
{\bf Note:} A {\it relation scheme} is just a kind of template
whereas a {\it relation} is an instance of a {\it relation
scheme}. The {\it relation} consists of tuples (and can therefore be
viewed as a table) not so the {\it relation scheme}.

\subsubsection{Domains vs. Data Types}
\label{domains}
We often talked about {\it domains} in the last section. Recall that a
domain is, formally, just a set of values (e.g., the set of integers or
the real numbers). In terms of database systems we often talk of {\it
data types} instead of domains. When we define a table we have to make
a decision about which attributes to include. Additionally we
have to decide which kind of data is going to be stored as
attribute values. For example the values of SNAME from the table
SUPPLIER will be character strings, whereas SNO will store
integers. We define this by assigning a {\it data type} to each
attribute. The type of SNAME will be VARCHAR(20) (this is the SQL type
for character strings of length $\le$ 20), the type of SNO will be
INTEGER. With the assignment of a {\it data type} we also have selected
a domain for an attribute. The domain of SNAME is the set of all
character strings of length $\le$ 20, the domain of SNO is the set of
all integer numbers.

\section{Operations in the Relational Data Model}
\label{operations}
In section \ref{formal_notion} we defined the mathematical notion of
the relational model. Now we know how the data can be stored using a
relational data model but we do not know what to do with all these
tables to retrieve something from the database yet. For example somebody
could ask for the names of all suppliers that sell the part
'Screw'. Therefore two rather different kinds of notations for
expressing operations on relations have been defined:
%
\begin{itemize}
\item The {\it Relational Algebra} which is an algebraic notation,
where queries are expressed by applying specialized operators to the
relations.
\item The {\it Relational Calculus} which is a logical notation,
where queries are expressed by formulating some logical restrictions
that the tuples in the answer must satisfy.
\end{itemize}
%
\subsection{Relational Algebra}
\label{rel_alg}
The {\it Relational Algebra} was introduced by E.~F.~Codd in 1972. It
consists of a set of operations on relations:
\begin{itemize}
\item SELECT ($\sigma$): extracts {\it tuples} from a relation that
satisfy a given restriction. Let $R$ be a table that contains an attribute
$A$. $\sigma_{A=a}(R) = \{t \in R \mid t(A) = a\}$ where $t$ denotes a
tuple of $R$ and $t(A)$ denotes the value of attribute $A$ of tuple $t$.
\item PROJECT ($\pi$): extracts specified {\it attributes} (columns) from a
relation. Let $R$ be a relation that contains an attribute $X$. $\pi_{X}(R) =
\{t(X) \mid t \in R\}$, where $t(X)$ denotes the value of attribute $X$ of
tuple $t$.
\item PRODUCT ($\times$): builds the Cartesian product of two
relations. Let $R$ be a table with arity $k_{1}$ and let $S$ be a table with
arity $k_{2}$. $R\times S$ is the set of all $(k_{1}+k_{2})$-tuples
whose first $k_{1}$ components form a tuple in $R$ and whose last
$k_{2}$ components form a tuple in $S$.
\item UNION ($\cup$): builds the set-theoretic union of two
tables. Given the tables $R$ and $S$ (both must have the same arity),
the union $R \cup S$ is the set of tuples that are in $R$ or $S$ or
both.
\item INTERSECT ($\cap$): builds the set-theoretic intersection of two
tables. Given the tables $R$ and $S$, $R \cup S$ is the set of tuples
that are in $R$ and in $S$. We again require that $R$ and $S$ have the
same arity.
\item DIFFERENCE ($-$ or $\setminus$): builds the set difference of
two tables. Let $R$ and $S$ again be two tables with the same
arity. $R-S$ is the set of tuples in $R$ but not in $S$.
\item JOIN ($\Join$): connects two tables by their common
attributes. Let $R$ be a table with the attributes $A,B$ and $C$ and
let $S$ a table with the attributes $C,D$ and $E$. There is one
attribute common to both relations, the attribute $C$. $R \Join S =
\pi_{R.A,R.B,R.C,S.D,S.E}(\sigma_{R.C=S.C}(R \times S))$. What are we
doing here? We first calculate the Cartesian product $R \times
S$. Then we select those tuples whose values for the common
attribute $C$ are equal ($\sigma_{R.C = S.C}$). Now we got a table
that contains the attribute $C$ two times and we correct this by
projecting out the duplicate column.
\begin{example} 
\label{join_example}
Let's have a look at the tables that are produced by evaluating the steps
necessary for a join. \\
Let the following two tables be given:
\begin{verbatim}
         R   A | B | C      S   C | D | E       
d492 12
a503 6
             1 | 2 | 3          3 | a | b       
             4 | 5 | 6          6 | c | d              
             7 | 8 | 9                                       
\end{verbatim}
First we calculate the Cartesian product $R \times S$ and get:
\begin{verbatim}
d512 9
a520 4
\end{verbatim}
\pagebreak
After the selection $\sigma_{R.C=S.C}(R \times S)$ we get:
\begin{verbatim}
d525 11
a535 5
\end{verbatim}
To remove the duplicate column $S.C$ we project it out by the
following operation: $\pi_{R.A,R.B,R.C,S.D,S.E}(\sigma_{R.C=S.C}(R
\times S))$ and get:
\begin{verbatim}
d540 31
a570 13
\end{verbatim}
\end{example}
\item DIVIDE ($\div$): Let $R$ be a table with the attributes $A,B,C$
and $D$ and let $S$ be a table with the attributes $C$ and $D$. Then
we define the division as: $R \div S = \{t \mid \forall t_{s} \in S~
\exists t_{r} \in R$ such that
$t_{r}(A,B)=t~\wedge~t_{r}(C,D)=t_{s}\}$ where $t_{r}(x,y)$ denotes a
tuple of table $R$ that consists only of the components $x$ and
$y$. Note that the tuple $t$ only consists of the components $A$ and
$B$ of relation $R$.
\begin{example}
Given the following tables
\begin{verbatim}
d579 6
a584 3
\end{verbatim}
$R \div S$ is derived as
\begin{verbatim}
d589 32
a620 22
\end{verbatim}
\end{example}
\end{itemize}
%
For a more detailed description and definition of the relational
algebra refer to \cite{ullman} or \cite{date86}.

\begin{example}
\label{suppl_rel_alg}
Recall that we formulated all those relational operators to be able to
retrieve data from the database. Let's return to our example of
section \ref{operations} where someone wanted to know the names of all
suppliers that sell the part 'Screw'. This question can be answered
using relational algebra by the following operation:
\begin{displaymath}
\pi_{SUPPLIER.SNAME}(\sigma_{PART.PNAME='Screw'}(SUPPLIER \Join SELLS
\Join PART))
\end{displaymath}
We call such an operation a query. If we evaluate the above query
against the tables form figure \ref{supplier} {\it The suppliers and
parts database} we will obtain the following result:
\begin{verbatim}
d625 161
a785 93
\end{verbatim}
\end{example}
\subsection{Relational Calculus}
\label{rel_calc}
The relational calculus is based on the {first order logic}. There are
two variants of the relational calculus:
%
\begin{itemize} 
\item The {\it Domain Relational Calculus} (DRC), where variables
stand for components (attributes) of the tuples.
\item The {\it Tuple Relational Calculus} (TRC), where variables stand
for tuples.
\end{itemize}
%
We want to discuss the tuple relational calculus only because it is
the one underlying the most relational languages. For a detailed
discussion on DRC (and also TRC) see \cite{date86} or \cite{ullman}.

\subsubsection{Tuple Relational Calculus}
The queries used in TRC are of the following form:
\begin{displaymath}
\{x(A) \mid F(x)\}
\end{displaymath}
where $x$ is a tuple variable $A$ is a set of attributes and $F$ is a
formula. The resulting relation consists of all tuples $t(A)$ that satisfy
$F(t)$.
\begin{example}
If we want to answer the question from example \ref{suppl_rel_alg}
using TRC we formulate the following query:
\begin{displaymath}
\begin{array}{lcll}
\{x(SNAME) & \mid & x \in SUPPLIER~\wedge & \nonumber\\ 
&  & \exists y \in SELLS\ \exists z \in PART & (y(SNO)=x(SNO)~\wedge \nonumber\\
&  &  &~ z(PNO)=y(PNO)~\wedge \nonumber\\
&  &  &~ z(PNAME)='Screw')\} \nonumber
\end{array}
\end{displaymath}
Evaluating the query against the tables from figure \ref{supplier}
{\it The suppliers and parts database} again leads to the same result
as in example \ref{suppl_rel_alg}.
\end{example}

\subsection{Relational Algebra vs. Relational Calculus}
\label{alg_vs_calc}
The relational algebra and the relational calculus have the same {\it
expressive power} i.e.\ all queries that can be formulated using
relational algebra can also be formulated using the relational
calculus and vice versa. This was first proved by E.~F.~Codd in
1972. This proof is based on an algorithm -"Codd's reduction
algorithm"- by which an arbitrary expression of the relational
calculus can be reduced to a semantically equivalent expression of
relational algebra. For a more detailed discussion on that refer to
\cite{date86} and
\cite{ullman}. 

It is sometimes said that languages based on the relational calculus
are "higher level" or "more declarative" than languages based on
relational algebra because the algebra (partially) specifies the order
of operations while the calculus leaves it to a compiler or
interpreter to determine the most efficient order of evaluation.


\section{The SQL Language}
\label{sqllanguage}
%
As most modern relational languages SQL is based on the tuple
relational calculus. As a result every query that can be formulated
using the tuple relational calculus (or equivalently, relational
algebra) can also be formulated using SQL. There are, however,
capabilities beyond the scope of relational algebra or calculus. Here
is a list of some additional features provided by SQL that are not
part of relational algebra or calculus:
\pagebreak
%
\begin{itemize}
\item Commands for insertion, deletion or modification of data.
\item Arithmetic capability: In SQL it is possible to involve
arithmetic operations as well as comparisons, e.g. $A < B + 3$. Note
that $+$ or other arithmetic operators appear neither in relational
algebra nor in relational calculus.
\item Assignment and Print Commands: It is possible to print a
relation constructed by a query and to assign a computed relation to a
relation name.
\item Aggregate Functions: Operations such as {\it average}, {\it
sum}, {\it max}, \ldots can be applied to columns of a relation to
obtain a single quantity.
\end{itemize}
%
\subsection{Select}
\label{select}
The most often used command in SQL is the SELECT statement that is
used to retrieve data. The syntax is:
\begin{verbatim}
d787 7
a793 7
          { * | <expr_1> [AS <c_alias_1>] [, ... 
                [, <expr_k> [AS <c_alias_k>]]]}
   FROM <table_name_1> [t_alias_1] 
        [, ... [, <table_name_n> [t_alias_n]]]
   [WHERE condition]
   [GROUP BY <name_of_attr_i> 
             [,... [, <name_of_attr_j>]] [HAVING condition]]
d795 31
a825 20
   [ORDER BY <name_of_attr_i> [ASC|DESC] 
             [, ... [, <name_of_attr_j> [ASC|DESC]]]];
\end{verbatim}
Now we will illustrate the complex syntax of the SELECT statement
with various examples. The tables used for the examples are defined in
figure \ref{supplier} {\it The suppliers and parts database}.
%
\subsubsection{Simple Selects}
\begin{example}
Here are some simple examples using a SELECT statement: \\
\\
To retrieve all tuples from table PART where the attribute PRICE is
greater than 10 we formulate the following query
\begin{verbatim}
   SELECT * 
   FROM PART
   WHERE PRICE > 10;
\end{verbatim}
and get the table:
\begin{verbatim}
d830 9
a838 6
\end{verbatim}
%
Using "$*$" in the SELECT statement will deliver all attributes from
the table. If we want to retrieve only the attributes PNAME and PRICE
from table PART we use the statement:
\begin{verbatim}
d842 5
a846 4
\end{verbatim}
\pagebreak
\noindent In this case the result is:
\begin{verbatim}
d851 13
a863 8
\end{verbatim}
Note that the SQL SELECT corresponds to the "projection" in relational
algebra not to the "selection" (see section \ref{rel_alg} {\it
Relational Algebra}).
\\ \\
The qualifications in the WHERE clause can also be logically connected
using the keywords OR, AND and NOT:
\begin{verbatim}
d868 5
a872 3
\end{verbatim}
will lead to the result:
\begin{verbatim}
d876 9
a884 5
\end{verbatim}
Arithmetic operations may be used in the {\it selectlist} and in the WHERE
clause. For example if we want to know how much it would cost if we
take two pieces of a part we could use the following query:
\begin{verbatim}
d888 5
a892 3
\end{verbatim}
and we get:
\begin{verbatim}
d898 25
a922 14
\end{verbatim}
Note that the word DOUBLE after the keyword AS is the new title of the
second column. This technique can be used for every element of the
{\it selectlist} to assign a new title to the resulting column. This new title
is often referred to as alias. The alias cannot be used throughout the
rest of the query. 
\end{example}

\subsubsection{Joins}
\begin{example} The following example shows how {\it joins} are
realized in SQL: \\ \\
To join the three tables SUPPLIER, PART and SELLS over their common
attributes we formulate the following statement:
\begin{verbatim}
d927 5
a931 4
\end{verbatim}
\pagebreak
\noindent and get the following table as a result:
\begin{verbatim}
d942 41
a982 25
\end{verbatim}
In the FROM clause we introduced an alias name for every relation
because there are common named attributes (SNO and PNO) among the
relations. Now we can distinguish between the common named attributes
by simply prefixing the attribute name with the alias name followed by
a dot. The join is calculated in the same way as shown in example
\ref{join_example}. First the Cartesian product $SUPPLIER\times PART
\times SELLS$ is derived. Now only those tuples satisfying the
conditions given in the WHERE clause are selected (i.e.\ the common
named attributes have to be equal). Finally we project out all
columns but S.SNAME and P.PNAME. 
\end{example}
%
\subsubsection{Aggregate Operators}
SQL provides aggregate operators (e.g. AVG, COUNT, SUM, MIN, MAX) that
take the name of an attribute as an argument. The value of the
aggregate operator is calculated over all values of the specified
attribute (column) of the whole table. If groups are specified in the
query the calculation is done only over the values of a group (see next
section).

\begin{example}
If we want to know the average cost of all parts in table PART we use
the following query:
\begin{verbatim}
d985 7
a991 3
\end{verbatim}
The result is:
\begin{verbatim}
d995 8
a1002 4
\end{verbatim}
If we want to know how many parts are stored in table PART we use
the statement:
\begin{verbatim}
d1005 5
a1009 3
\end{verbatim}
and get:
\begin{verbatim}
d1013 1
a1013 2
\end{verbatim}
\end{example}
d1015 36
a1050 18
\subsubsection{Aggregation by Groups}
SQL allows to partition the tuples of a table into groups. Then the
aggregate operators described above can be applied to the groups
(i.e. the value of the aggregate operator is no longer calculated over
all the values of the specified column but over all values of a
group. Thus the aggregate operator is evaluated individually for every
group.) 
\\ \\
The partitioning of the tuples into groups is done by using the
keywords \mbox{GROUP BY} followed by a list of attributes that define the
groups. If we have {\tt GROUP BY $A_{1}, \ldots, A_{k}$} we partition
the relation into groups, such that two tuples are in the same group
if and only if they agree on all the attributes $A_{1}, \ldots,
A_{k}$.
\begin{example}
If we want to know how many parts are sold by every supplier we
formulate the query:
\begin{verbatim}
d1055 5
a1059 3
\end{verbatim}
and get:
\begin{verbatim}
d1066 9
a1074 5
\end{verbatim}
Now let's have a look of what is happening here: \\
First the join of the
tables SUPPLIER and SELLS is derived:
\begin{verbatim}
d1085 8
a1092 4
\end{verbatim}
Next we partition the tuples into groups by putting all tuples
together that agree on both attributes S.SNO and S.SNAME:
\begin{verbatim}
d1106 41
a1146 26
\end{verbatim}
In our example we got four groups and now we can apply the aggregate
operator COUNT to every group leading to the total result of the query
given above.
\end{example}
%
 Note that for the result of a query using GROUP BY and aggregate
operators to make sense the attributes grouped by must also appear in
the {\it selectlist}. All further attributes not appearing in the GROUP
BY clause can only be selected by using an aggregate function. On
the other hand you can not use aggregate functions on attributes
appearing in the GROUP BY clause.

\subsubsection{Having}

The HAVING clause works much like the WHERE clause and is used to
consider only those groups satisfying the qualification given in the
HAVING clause. The expressions allowed in the HAVING clause must
involve aggregate functions. Every expression using only  plain
attributes belongs to the WHERE clause. On the other hand every
expression involving an aggregate function must be put to the HAVING
clause. 
\begin{example}
If we want only those suppliers selling more than one part we use the
query:
\begin{verbatim}
d1152 5
a1156 3
\end{verbatim}
and get:
\begin{verbatim}
d1162 22
a1183 2
\end{verbatim}
\end{example}
d1185 1
a1185 9
\subsubsection{Subqueries}
In the WHERE and HAVING clauses the use of subqueries (subselects) is
allowed in every place where a value is expected. In this case the
value must be derived by evaluating the subquery first. The usage of
subqueries extends the expressive power of SQL.
\begin{example}
If we want to know all parts having a greater price than the part
named 'Screw' we use the query:
\begin{verbatim}
d1190 7
a1196 3
\end{verbatim}
The result is:
\begin{verbatim}
d1201 19
a1219 13
\end{verbatim}
When we look at the above query we can see
the keyword SELECT two times. The first one at the beginning of the
query - we will refer to it as outer SELECT - and the one in the WHERE
clause which begins a nested query - we will refer to it as inner
SELECT. For every tuple of the outer SELECT the inner SELECT has to be
evaluated. After every evaluation we know the price of the tuple named
'Screw' and we can check if the price of the actual tuple is
greater. 
\\ \\
\noindent If we want to know all suppliers that do not sell any part 
(e.g. to be able to remove these suppliers from the database) we use:
\begin{verbatim}
d1225 28
a1252 15
\end{verbatim}
In our example the result will be empty because every supplier sells
at least one part. Note that we use S.SNO from the outer SELECT within
the WHERE clause of the inner SELECT. As described above the subquery
is evaluated for every tuple from the outer query i.e. the value for
S.SNO is always taken from the actual tuple of the outer SELECT. 
\end{example}

\subsubsection{Union, Intersect, Except}

These operations calculate the union, intersect and set theoretic
difference of the tuples derived by two subqueries:
\begin{example}
The following query is an example for UNION:
\begin{verbatim}
d1260 2
a1261 1
\end{verbatim}
d1263 2
a1264 1
\begin{verbatim}
d1269 7
a1275 3
\end{verbatim}
Here an example for INTERSECT:
\begin{verbatim}
d1283 5
a1287 3
\end{verbatim}
gives the result:
\begin{verbatim}
a1290 1
\end{verbatim}
d1292 5
a1296 1
\pagebreak
d1298 1
a1298 2
\noindent Finally an example for EXCEPT:
\begin{verbatim}
d1306 5
a1310 3
\end{verbatim}
gives the result:
\begin{verbatim}
d1315 27
a1341 19
\end{verbatim}
\end{example}
%
\subsection{Data Definition}
\label{datadef}
%
There is a set of commands used for data definition included in the
SQL language. 

\subsubsection{Create Table}
\label{create}
The most fundamental command for data definition is the
one that creates a new relation (a new table). The syntax of the
CREATE TABLE command is:
%
\begin{verbatim}
   CREATE TABLE <table_name>
                (<name_of_attr_1> <type_of_attr_1>
                 [, <name_of_attr_2> <type_of_attr_2> 
d1343 11
a1353 6
\end{verbatim}
%
\begin{example}
To create the tables defined in figure \ref{supplier} the
following SQL statements are used:
\begin{verbatim}
d1358 3
a1360 1
   
d1365 3
a1367 2
\end{verbatim}
\begin{verbatim}
d1371 98
a1468 2
\end{verbatim}
\end{example}
d1470 1
a1470 32
%
\subsubsection{Data Types in SQL}
The following is a list of some data types that are supported by SQL:
\begin{itemize}
\item INTEGER: signed fullword binary integer (31 bits precision).
\item SMALLINT: signed halfword binary integer (15 bits precision).
\item DECIMAL ($p \lbrack,q\rbrack $): signed packed decimal number of $p$
digits precision with assumed $q$ of them right to the decimal
point. $(15\ge p \ge q \ge 0)$. If $q$ is omitted it is assumed to be 0.
\item FLOAT: signed doubleword floating point number.
\item CHAR($n$): fixed length character string of length $n$.
\item VARCHAR($n$): varying length character string of maximum length
$n$.
\end{itemize}

\subsubsection{Create Index}
Indices are used to speed up access to a relation. If a relation $R$
has an index on attribute $A$ then we can retrieve all tuples $t$
having $t(A) = a$ in time roughly proportional to the number of such
tuples $t$ rather than in time proportional to the size of $R$.

To create an index in SQL the CREATE INDEX command is used. The syntax
is:
\begin{verbatim}
   CREATE INDEX <index_name> 
   ON <table_name> ( <name_of_attribute> );
\end{verbatim}
%
\begin{example}
To create an index named I on attribute SNAME of relation SUPPLIER
we use the following statement:
\begin{verbatim}
d1473 63
a1535 38
\end{verbatim}
\end{example}
%
The created index is maintained automatically, i.e.\ whenever a new tuple
is inserted into the relation SUPPLIER the index I is adapted. Note
that the only changes a user can percept when an index is present
are an increased speed.

\subsubsection{Create View}
A view may be regarded as a {\it virtual table}, i.e.\ a table that
does not {\it physically} exist in the database but looks to the user
as if it did. By contrast, when we talk of a {\it base table} there is
really a physically stored counterpart of each row of the table
somewhere in the physical storage.

Views do not have their own, physically separate, distinguishable
stored data. Instead, the system stores the {\it definition} of the
view (i.e.\ the rules about how to access physically stored {\it base
tables} in order to materialize the view) somewhere in the {\it system
catalogs} (see section \ref{catalogs} {\it System Catalogs}). For a
discussion on different techniques to implement views refer to section
\ref{view_impl} {\it Techniques To Implement Views}.

In SQL the CREATE VIEW command is used to define a view. The syntax
is:
\begin{verbatim}
   CREATE VIEW <view_name>
   AS <select_stmt>
\end{verbatim}
where {\tt $<$select\_stmt$>$ } is a valid select statement as defined
in section \ref{select}. Note that the {\tt $<$select\_stmt$>$ } is
not executed when the view is created. It is just stored in the {\it
system catalogs} and is executed whenever a query against the view is
made.
\begin{example} Let the following view definition be given (we use
the tables from figure \ref{supplier} {\it The suppliers and parts
database} again):
\begin{verbatim}
d1542 9
a1550 4
\end{verbatim}
Now we can use this {\it virtual relation} {\tt London\_Suppliers} as
if it were another base table:
\begin{verbatim}
d1554 5
a1558 3
\end{verbatim}
will return the following table:
\begin{verbatim}
d1562 30
a1591 18
\end{verbatim}
To calculate this result the database system has to do a {\it hidden}
access to the base tables SUPPLIER, SELLS and PART first. It
does so by executing the query given in the view definition against
those base tables. After that the additional qualifications (given in the
query against the view) can be applied to obtain the resulting table.
\end{example}

\subsubsection{Drop Table, Drop Index, Drop View}
To destroy a table (including all tuples stored in that table) the
DROP TABLE command is used:
\begin{verbatim}
   DROP TABLE <table_name>;
\end{verbatim}
%
\begin{example}
To destroy the SUPPLIER table use the following statement:
\begin{verbatim}
d1593 47
a1639 30
\end{verbatim}
\end{example}
%
The DROP INDEX command is used to destroy an index:
\begin{verbatim}
   DROP INDEX <index_name>;
\end{verbatim}
%
Finally to destroy a given view use the command DROP VIEW:
\begin{verbatim}
   DROP VIEW <view_name>;
\end{verbatim}

\subsection{Data Manipulation}
%
\subsubsection{Insert Into}
Once a table is created (see section \ref{create}), it can be filled
with tuples using the command INSERT INTO. The syntax is:
\begin{verbatim}
   INSERT INTO <table_name> (<name_of_attr_1> 
                             [, <name_of_attr_2> [,...]])
   VALUES (<val_attr_1> 
           [, <val_attr_2> [, ...]]);
\end{verbatim}
%
\begin{example}
To insert the first tuple into the relation SUPPLIER of figure
\ref{supplier} {\it The suppliers and parts database} we use the
following statement:
\begin{verbatim}
d1642 7
a1648 4
\end{verbatim}
%
To insert the first tuple into the relation SELLS we use:
\begin{verbatim}
d1651 22
a1672 2
\end{verbatim}
\end{example}
d1674 1
a1674 14
\subsubsection{Update}
To change one or more attribute values of tuples in a relation the
UPDATE command is used. The syntax is:
\begin{verbatim}
   UPDATE <table_name>
   SET <name_of_attr_1> = <value_1> 
       [, ... [, <name_of_attr_k> = <value_k>]]
   WHERE <condition>;
\end{verbatim}
%
\begin{example}
To change the value of attribute PRICE of the part 'Screw' in the
relation PART we use:
\begin{verbatim}
d1678 27
a1704 16
\end{verbatim}
The new value of attribute PRICE of the tuple whose name is 'Screw' is
now 15.
\end{example}

\subsubsection{Delete}
To delete a tuple from a particular table use the command DELETE
FROM. The syntax is:
\begin{verbatim}
   DELETE FROM <table_name>
   WHERE <condition>;
\end{verbatim}
\begin{example}
To delete the supplier called 'Smith' of the table SUPPLIER the
following statement is used:
\begin{verbatim}
d1707 91
a1797 51
\end{verbatim}
\end{example}
%
\subsection{System Catalogs}
\label{catalogs}
In every SQL database system {\it system catalogs} are used to keep
track of which tables, views indexes etc. are defined in the
database. These system catalogs can be queried as if they were normal
relations. For example there is one catalog used for the definition of
views. This catalog stores the query from the view definition. Whenever
a query against a view is made, the system first gets the {\it
view-definition-query} out of the catalog and materializes the view
before proceeding with the user query (see section \ref{view_impl}
{\it Techniques To Implement Views} for a more detailed
description). For more information about {\it system catalogs} refer to
\cite{date}.

\subsection{Embedded SQL}

In this section we will sketch how SQL can be embedded into a host
language (e.g.\ C). There are two main reasons why we want to use SQL
from a host language:
%
\begin{itemize}
\item There are queries that cannot be formulated using pure SQL
(i.e. recursive queries). To be able to perform such queries we need a
host language with a greater expressive power than SQL.
\item We simply want to access a database from some application that
is written in the host language (e.g.\ a ticket reservation system
with a graphical user interface is written in C and the information
about which tickets are still left is stored in a database that can be
accessed using embedded SQL).
\end{itemize}
%
A program using embedded SQL in a host language consists of statements
of the host language and of embedded SQL (ESQL) statements. Every ESQL
statement begins with the keywords EXEC SQL. The ESQL statements are
transformed to statements of the host language by a {\it precompiler}
(mostly calls to library routines that perform the various SQL
commands). 

When we look at the examples throughout section \ref{select} we
realize that the result of the queries is very often a set of
tuples. Most host languages are not designed to operate on sets so we
need a mechanism to access every single tuple of the set of tuples
returned by a SELECT statement. This mechanism can be provided by
declaring a {\it cursor}. After that we can use the FETCH command to
retrieve a tuple and set the cursor to the next tuple.
\\ \\
For a detailed discussion on embedded SQL refer to \cite{date},
\cite{date86} or \cite{ullman}.
d1802 1
a1802 1
sgml-omittag:f
@


1.1
log
@Introduction to SQL from Stefan. Not yet marked up, but will go into
 the User's Guide sometime soon.
@
text
@d466 1
a466 1
   [{UNION | INTERSECT | EXCEPT} SELECT ...]
@
