Commit 4ab7ea5a authored by Bruce Momjian's avatar Bruce Momjian

Remove tabs from SGML files to help tag alingment and improve

detection of tabs are added in the future.
parent 7ea758b0
<!-- $PostgreSQL: pgsql/doc/src/sgml/docguide.sgml,v 1.70 2007/02/01 00:28:16 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/docguide.sgml,v 1.71 2007/02/16 03:50:28 momjian Exp $ -->
<appendix id="docguide"> <appendix id="docguide">
<title>Documentation</title> <title>Documentation</title>
...@@ -227,7 +227,7 @@ ...@@ -227,7 +227,7 @@
<para> <para>
It's possible that the ports do not update the main catalog file It's possible that the ports do not update the main catalog file
in <filename>/usr/local/share/sgml/catalog.ports</filename> or order in <filename>/usr/local/share/sgml/catalog.ports</filename> or order
isn't proper . Be sure to have the following lines in begining of file: isn't proper . Be sure to have the following lines in begining of file:
<programlisting> <programlisting>
CATALOG "openjade/catalog" CATALOG "openjade/catalog"
CATALOG "iso8879/catalog" CATALOG "iso8879/catalog"
......
This source diff could not be displayed because it is too large. You can view the blob instead.
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.359 2007/02/16 03:39:44 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.360 2007/02/16 03:50:29 momjian Exp $ -->
<chapter id="functions"> <chapter id="functions">
<title>Functions and Operators</title> <title>Functions and Operators</title>
...@@ -4804,15 +4804,15 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})'); ...@@ -4804,15 +4804,15 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
An ISO week date (as distinct from a Gregorian date) can be specified to <function>to_timestamp</function> and <function>to_date</function> in one of two ways: An ISO week date (as distinct from a Gregorian date) can be specified to <function>to_timestamp</function> and <function>to_date</function> in one of two ways:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
Year, week and weekday, for example <literal>to_date('2006-42-4', 'IYYY-IW-ID')</literal> returns the date <literal>2006-10-19</literal>. If you omit the weekday it is assumed to be 1 (Monday). Year, week and weekday, for example <literal>to_date('2006-42-4', 'IYYY-IW-ID')</literal> returns the date <literal>2006-10-19</literal>. If you omit the weekday it is assumed to be 1 (Monday).
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Year and day of year, for example <literal>to_date('2006-291', 'IYYY-IDDD')</literal> also returns <literal>2006-10-19</literal>. Year and day of year, for example <literal>to_date('2006-291', 'IYYY-IDDD')</literal> also returns <literal>2006-10-19</literal>.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para> <para>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/geqo.sgml,v 1.38 2006/09/16 00:30:14 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/geqo.sgml,v 1.39 2007/02/16 03:50:29 momjian Exp $ -->
<chapter id="geqo"> <chapter id="geqo">
<chapterinfo> <chapterinfo>
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
<productname>PostgreSQL</productname>) to process individual joins <productname>PostgreSQL</productname>) to process individual joins
and a diversity of <firstterm>indexes</firstterm> (e.g., and a diversity of <firstterm>indexes</firstterm> (e.g.,
B-tree, hash, GiST and GIN in <productname>PostgreSQL</productname>) as B-tree, hash, GiST and GIN in <productname>PostgreSQL</productname>) as
access paths for relations. access paths for relations.
</para> </para>
<para> <para>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/gin.sgml,v 2.10 2007/02/01 19:10:24 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/gin.sgml,v 2.11 2007/02/16 03:50:29 momjian Exp $ -->
<chapter id="GIN"> <chapter id="GIN">
<title>GIN Indexes</title> <title>GIN Indexes</title>
...@@ -100,12 +100,12 @@ ...@@ -100,12 +100,12 @@
to consult <literal>n</> to determine the data type of to consult <literal>n</> to determine the data type of
<literal>query</> and the key values that need to be extracted. <literal>query</> and the key values that need to be extracted.
The number of returned keys must be stored into <literal>*nkeys</>. The number of returned keys must be stored into <literal>*nkeys</>.
If number of keys is equal to zero then <function>extractQuery</> If number of keys is equal to zero then <function>extractQuery</>
should store 0 or -1 into <literal>*nkeys</>. 0 means that any should store 0 or -1 into <literal>*nkeys</>. 0 means that any
row matches the <literal>query</> and sequence scan should be row matches the <literal>query</> and sequence scan should be
produced. -1 means nothing can satisfy <literal>query</>. produced. -1 means nothing can satisfy <literal>query</>.
Choice of value should be based on semantics meaning of operation with Choice of value should be based on semantics meaning of operation with
given strategy number. given strategy number.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.229 2007/02/16 02:59:40 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.230 2007/02/16 03:50:29 momjian Exp $ -->
<chapter id="libpq"> <chapter id="libpq">
<title><application>libpq</application> - C Library</title> <title><application>libpq</application> - C Library</title>
...@@ -334,9 +334,9 @@ PGconn *PQsetdbLogin(const char *pghost, ...@@ -334,9 +334,9 @@ PGconn *PQsetdbLogin(const char *pghost,
</para> </para>
<para> <para>
If the <parameter>dbName</parameter> contains an <symbol>=</symbol> sign, it If the <parameter>dbName</parameter> contains an <symbol>=</symbol> sign, it
is taken as a <parameter>conninfo</parameter> string in exactly the same way as is taken as a <parameter>conninfo</parameter> string in exactly the same way as
if it had been passed to <function>PQconnectdb</function>, and the remaining if it had been passed to <function>PQconnectdb</function>, and the remaining
parameters are then applied as above. parameters are then applied as above.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -4486,8 +4486,8 @@ ldap://ldap.mycompany.com/dc=mycompany,dc=com?uniqueMember?one?(cn=mydatabase) ...@@ -4486,8 +4486,8 @@ ldap://ldap.mycompany.com/dc=mycompany,dc=com?uniqueMember?one?(cn=mydatabase)
do not reveal secret keys to the application. Instead, applications do not reveal secret keys to the application. Instead, applications
delegate all cryptography operations which require the secret key to delegate all cryptography operations which require the secret key to
the hardware token. the hardware token.
</para> </para>
<para> <para>
If the file <filename>~/.postgresql/root.crt</> is present in the user's If the file <filename>~/.postgresql/root.crt</> is present in the user's
home directory, home directory,
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/mvcc.sgml,v 2.67 2007/02/08 15:32:11 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/mvcc.sgml,v 2.68 2007/02/16 03:50:29 momjian Exp $ -->
<chapter id="mvcc"> <chapter id="mvcc">
<title>Concurrency Control</title> <title>Concurrency Control</title>
...@@ -754,7 +754,7 @@ SELECT SUM(value) FROM mytab WHERE class = 2; ...@@ -754,7 +754,7 @@ SELECT SUM(value) FROM mytab WHERE class = 2;
<colspec colnum="8" colwidth="1*"> <colspec colnum="8" colwidth="1*">
<colspec colnum="9" colwidth="1*"> <colspec colnum="9" colwidth="1*">
<thead> <thead>
<row> <row>
<entry>Modes</entry> <entry>Modes</entry>
<entry>AS</entry> <entry>AS</entry>
<entry>RS</entry> <entry>RS</entry>
...@@ -764,10 +764,10 @@ SELECT SUM(value) FROM mytab WHERE class = 2; ...@@ -764,10 +764,10 @@ SELECT SUM(value) FROM mytab WHERE class = 2;
<entry>SRE</entry> <entry>SRE</entry>
<entry>E</entry> <entry>E</entry>
<entry>AE</entry> <entry>AE</entry>
</row> </row>
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry>AS</entry> <entry>AS</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
...@@ -777,8 +777,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2; ...@@ -777,8 +777,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2;
<entry align="center">Y</entry> <entry align="center">Y</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
</row> </row>
<row> <row>
<entry>RS</entry> <entry>RS</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
...@@ -788,8 +788,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2; ...@@ -788,8 +788,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2;
<entry align="center">Y</entry> <entry align="center">Y</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
</row> </row>
<row> <row>
<entry>RE</entry> <entry>RE</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
...@@ -799,8 +799,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2; ...@@ -799,8 +799,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2;
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
</row> </row>
<row> <row>
<entry>SUE</entry> <entry>SUE</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
...@@ -810,8 +810,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2; ...@@ -810,8 +810,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2;
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
</row> </row>
<row> <row>
<entry>S</entry> <entry>S</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
...@@ -821,8 +821,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2; ...@@ -821,8 +821,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2;
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
</row> </row>
<row> <row>
<entry>SRE</entry> <entry>SRE</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
...@@ -832,8 +832,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2; ...@@ -832,8 +832,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2;
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
</row> </row>
<row> <row>
<entry>E</entry> <entry>E</entry>
<entry align="center">Y</entry> <entry align="center">Y</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
...@@ -843,8 +843,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2; ...@@ -843,8 +843,8 @@ SELECT SUM(value) FROM mytab WHERE class = 2;
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
</row> </row>
<row> <row>
<entry>AE</entry> <entry>AE</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
...@@ -854,10 +854,10 @@ SELECT SUM(value) FROM mytab WHERE class = 2; ...@@ -854,10 +854,10 @@ SELECT SUM(value) FROM mytab WHERE class = 2;
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
<entry align="center">N</entry> <entry align="center">N</entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
</sect2> </sect2>
<sect2 id="locking-rows"> <sect2 id="locking-rows">
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.63 2007/02/01 19:10:24 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.64 2007/02/16 03:50:29 momjian Exp $ -->
<chapter id="plperl"> <chapter id="plperl">
<title>PL/Perl - Perl Procedural Language</title> <title>PL/Perl - Perl Procedural Language</title>
...@@ -649,19 +649,19 @@ $$ LANGUAGE plperl; ...@@ -649,19 +649,19 @@ $$ LANGUAGE plperl;
<note> <note>
<para> <para>
For security reasons, to stop a leak of privileged operations from For security reasons, to stop a leak of privileged operations from
<application>PL/PerlU</> to <application>PL/Perl</>, these two languages <application>PL/PerlU</> to <application>PL/Perl</>, these two languages
have to run in separate instances of the Perl interpreter. If your have to run in separate instances of the Perl interpreter. If your
Perl installation has been appropriately compiled, this is not a problem. Perl installation has been appropriately compiled, this is not a problem.
However, not all installations are compiled with the requisite flags. However, not all installations are compiled with the requisite flags.
If <productname>PostgreSQL</> detects that this is the case then it will If <productname>PostgreSQL</> detects that this is the case then it will
not start a second interpreter, but instead create an error. In not start a second interpreter, but instead create an error. In
consequence, in such an installation, you cannot use both consequence, in such an installation, you cannot use both
<application>PL/PerlU</> and <application>PL/Perl</> in the same backend <application>PL/PerlU</> and <application>PL/Perl</> in the same backend
process. The remedy for this is to obtain a Perl installation created process. The remedy for this is to obtain a Perl installation created
with the appropriate flags, namely either <literal>usemultiplicity</> or with the appropriate flags, namely either <literal>usemultiplicity</> or
both <literal>usethreads</> and <literal>useithreads</>. both <literal>usethreads</> and <literal>useithreads</>.
For more details,see the <literal>perlembed</> manual page. For more details,see the <literal>perlembed</> manual page.
</para> </para>
</note> </note>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.45 2007/02/01 19:10:24 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.46 2007/02/16 03:50:29 momjian Exp $ -->
<chapter id="sql-intro"> <chapter id="sql-intro">
<title>SQL</title> <title>SQL</title>
...@@ -414,139 +414,139 @@ attributes are taken from. We often write a relation scheme as ...@@ -414,139 +414,139 @@ attributes are taken from. We often write a relation scheme as
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
SELECT (&sigma;): extracts <firstterm>tuples</firstterm> from SELECT (&sigma;): extracts <firstterm>tuples</firstterm> from
a relation that a relation that
satisfy a given restriction. Let <parameter>R</parameter> be a satisfy a given restriction. Let <parameter>R</parameter> be a
table that contains an attribute table that contains an attribute
<parameter>A</parameter>. <parameter>A</parameter>.
&sigma;<subscript>A=a</subscript>(R) = {t &isin; R &mid; t(A) = a} &sigma;<subscript>A=a</subscript>(R) = {t &isin; R &mid; t(A) = a}
where <literal>t</literal> denotes a where <literal>t</literal> denotes a
tuple of <parameter>R</parameter> and <literal>t(A)</literal> tuple of <parameter>R</parameter> and <literal>t(A)</literal>
denotes the value of attribute <parameter>A</parameter> of denotes the value of attribute <parameter>A</parameter> of
tuple <literal>t</literal>. tuple <literal>t</literal>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
PROJECT (&pi;): extracts specified PROJECT (&pi;): extracts specified
<firstterm>attributes</firstterm> (columns) from a <firstterm>attributes</firstterm> (columns) from a
relation. Let <classname>R</classname> be a relation relation. Let <classname>R</classname> be a relation
that contains an attribute <classname>X</classname>. that contains an attribute <classname>X</classname>.
&pi;<subscript>X</subscript>(<classname>R</classname>) = {t(X) &mid; t &isin; <classname>R</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 where <literal>t</literal>(<classname>X</classname>) denotes the value of
attribute <classname>X</classname> of tuple <literal>t</literal>. attribute <classname>X</classname> of tuple <literal>t</literal>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
PRODUCT (&times;): builds the Cartesian product of two PRODUCT (&times;): builds the Cartesian product of two
relations. Let <classname>R</classname> be a table with arity relations. Let <classname>R</classname> be a table with arity
<literal>k</literal><subscript>1</subscript> and let <literal>k</literal><subscript>1</subscript> and let
<classname>S</classname> be a table with <classname>S</classname> be a table with
arity <literal>k</literal><subscript>2</subscript>. arity <literal>k</literal><subscript>2</subscript>.
<classname>R</classname> &times; <classname>S</classname> <classname>R</classname> &times; <classname>S</classname>
is the set of all is the set of all
<literal>k</literal><subscript>1</subscript> <literal>k</literal><subscript>1</subscript>
+ <literal>k</literal><subscript>2</subscript>-tuples + <literal>k</literal><subscript>2</subscript>-tuples
whose first <literal>k</literal><subscript>1</subscript> whose first <literal>k</literal><subscript>1</subscript>
components form a tuple in <classname>R</classname> and whose last components form a tuple in <classname>R</classname> and whose last
<literal>k</literal><subscript>2</subscript> components form a <literal>k</literal><subscript>2</subscript> components form a
tuple in <classname>S</classname>. tuple in <classname>S</classname>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
UNION (&cup;): builds the set-theoretic union of two UNION (&cup;): builds the set-theoretic union of two
tables. Given the tables <classname>R</classname> and tables. Given the tables <classname>R</classname> and
<classname>S</classname> (both must have the same arity), <classname>S</classname> (both must have the same arity),
the union <classname>R</classname> &cup; <classname>S</classname> the union <classname>R</classname> &cup; <classname>S</classname>
is the set of tuples that are in <classname>R</classname> is the set of tuples that are in <classname>R</classname>
or <classname>S</classname> or both. or <classname>S</classname> or both.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
INTERSECT (&cap;): builds the set-theoretic intersection of two INTERSECT (&cap;): builds the set-theoretic intersection of two
tables. Given the tables <classname>R</classname> and tables. Given the tables <classname>R</classname> and
<classname>S</classname>, <classname>S</classname>,
<classname>R</classname> &cap; <classname>S</classname> is the <classname>R</classname> &cap; <classname>S</classname> is the
set of tuples set of tuples
that are in <classname>R</classname> and in that are in <classname>R</classname> and in
<classname>S</classname>. <classname>S</classname>.
We again require that <classname>R</classname> and We again require that <classname>R</classname> and
<classname>S</classname> have the <classname>S</classname> have the
same arity. same arity.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
DIFFERENCE (&minus; or &setmn;): builds the set difference of DIFFERENCE (&minus; or &setmn;): builds the set difference of
two tables. Let <classname>R</classname> and <classname>S</classname> two tables. Let <classname>R</classname> and <classname>S</classname>
again be two tables with the same again be two tables with the same
arity. <classname>R</classname> - <classname>S</classname> arity. <classname>R</classname> - <classname>S</classname>
is the set of tuples in <classname>R</classname> but not in is the set of tuples in <classname>R</classname> but not in
<classname>S</classname>. <classname>S</classname>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
JOIN (&prod;): connects two tables by their common JOIN (&prod;): connects two tables by their common
attributes. Let <classname>R</classname> be a table with the attributes. Let <classname>R</classname> be a table with the
attributes <classname>A</classname>,<classname>B</classname> attributes <classname>A</classname>,<classname>B</classname>
and <classname>C</classname> and and <classname>C</classname> and
let <classname>S</classname> be a table with the attributes let <classname>S</classname> be a table with the attributes
<classname>C</classname>,<classname>D</classname> <classname>C</classname>,<classname>D</classname>
and <classname>E</classname>. There is one and <classname>E</classname>. There is one
attribute common to both relations, attribute common to both relations,
the attribute <classname>C</classname>. the attribute <classname>C</classname>.
<!-- <!--
<classname>R</classname> &prod; <classname>S</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>)). &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)). 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 What are we doing here? We first calculate the Cartesian
product product
<classname>R</classname> &times; <classname>S</classname>. <classname>R</classname> &times; <classname>S</classname>.
Then we select those tuples whose values for the common Then we select those tuples whose values for the common
attribute <classname>C</classname> are equal attribute <classname>C</classname> are equal
(&sigma;<subscript>R.C = S.C</subscript>). (&sigma;<subscript>R.C = S.C</subscript>).
Now we have a table Now we have a table
that contains the attribute <classname>C</classname> that contains the attribute <classname>C</classname>
two times and we correct this by two times and we correct this by
projecting out the duplicate column. projecting out the duplicate column.
</para> </para>
<example> <example>
<title id="join-example">An Inner Join</title> <title id="join-example">An Inner Join</title>
<para> <para>
Let's have a look at the tables that are produced by evaluating the steps Let's have a look at the tables that are produced by evaluating the steps
necessary for a join. necessary for a join.
Let the following two tables be given: Let the following two tables be given:
<programlisting> <programlisting>
R: S: R: S:
A | B | C C | D | E A | B | C C | D | E
---+---+--- ---+---+--- ---+---+--- ---+---+---
1 | 2 | 3 3 | a | b 1 | 2 | 3 3 | a | b
4 | 5 | 6 6 | c | d 4 | 5 | 6 6 | c | d
7 | 8 | 9 7 | 8 | 9
</programlisting> </programlisting>
</para> </para>
</example> </example>
<para> <para>
First we calculate the Cartesian product First we calculate the Cartesian product
<classname>R</classname> &times; <classname>S</classname> and <classname>R</classname> &times; <classname>S</classname> and
get: get:
<programlisting> <programlisting>
R x S: R x S:
A | B | R.C | S.C | D | E A | B | R.C | S.C | D | E
---+---+-----+-----+---+--- ---+---+-----+-----+---+---
...@@ -556,66 +556,66 @@ R x S: ...@@ -556,66 +556,66 @@ R x S:
4 | 5 | 6 | 6 | c | d 4 | 5 | 6 | 6 | c | d
7 | 8 | 9 | 3 | a | b 7 | 8 | 9 | 3 | a | b
7 | 8 | 9 | 6 | c | d 7 | 8 | 9 | 6 | c | d
</programlisting> </programlisting>
</para> </para>
<para> <para>
After the selection After the selection
&sigma;<subscript>R.C=S.C</subscript>(R &times; S) &sigma;<subscript>R.C=S.C</subscript>(R &times; S)
we get: we get:
<programlisting> <programlisting>
A | B | R.C | S.C | D | E A | B | R.C | S.C | D | E
---+---+-----+-----+---+--- ---+---+-----+-----+---+---
1 | 2 | 3 | 3 | a | b 1 | 2 | 3 | 3 | a | b
4 | 5 | 6 | 6 | c | d 4 | 5 | 6 | 6 | c | d
</programlisting> </programlisting>
</para> </para>
<para> <para>
To remove the duplicate column To remove the duplicate column
<classname>S</classname>.<classname>C</classname> <classname>S</classname>.<classname>C</classname>
we project it out by the following operation: 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)) &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: and get:
<programlisting> <programlisting>
A | B | C | D | E A | B | C | D | E
---+---+---+---+--- ---+---+---+---+---
1 | 2 | 3 | a | b 1 | 2 | 3 | a | b
4 | 5 | 6 | c | d 4 | 5 | 6 | c | d
</programlisting> </programlisting>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
DIVIDE (&divide;): Let <classname>R</classname> be a table DIVIDE (&divide;): Let <classname>R</classname> be a table
with the attributes A, B, C, and D and let with the attributes A, B, C, and D and let
<classname>S</classname> be a table with the attributes <classname>S</classname> be a table with the attributes
C and D. C and D.
Then we define the division as: Then we define the division as:
<programlisting> <programlisting>
R &divide; S = {t &mid; &forall; t<subscript>s</subscript> &isin; S &exist; t<subscript>r</subscript> &isin; R R &divide; S = {t &mid; &forall; t<subscript>s</subscript> &isin; S &exist; t<subscript>r</subscript> &isin; R
</programlisting> </programlisting>
such that such that
t<subscript>r</subscript>(A,B)=t&and;t<subscript>r</subscript>(C,D)=t<subscript>s</subscript>} t<subscript>r</subscript>(A,B)=t&and;t<subscript>r</subscript>(C,D)=t<subscript>s</subscript>}
where where
t<subscript>r</subscript>(x,y) t<subscript>r</subscript>(x,y)
denotes a denotes a
tuple of table <classname>R</classname> that consists only of tuple of table <classname>R</classname> that consists only of
the components <literal>x</literal> and <literal>y</literal>. the components <literal>x</literal> and <literal>y</literal>.
Note that the tuple <literal>t</literal> only consists of the Note that the tuple <literal>t</literal> only consists of the
components <classname>A</classname> and components <classname>A</classname> and
<classname>B</classname> of relation <classname>R</classname>. <classname>B</classname> of relation <classname>R</classname>.
</para> </para>
<para id="divide-example"> <para id="divide-example">
Given the following tables Given the following tables
<programlisting> <programlisting>
R: S: R: S:
A | B | C | D C | D A | B | C | D C | D
---+---+---+--- ---+--- ---+---+---+--- ---+---
...@@ -625,17 +625,17 @@ R: S: ...@@ -625,17 +625,17 @@ R: S:
e | d | c | d e | d | c | d
e | d | e | f e | d | e | f
a | b | d | e a | b | d | e
</programlisting> </programlisting>
R &divide; S R &divide; S
is derived as is derived as
<programlisting> <programlisting>
A | B A | B
---+--- ---+---
a | b a | b
e | d e | d
</programlisting> </programlisting>
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
...@@ -691,16 +691,16 @@ R: S: ...@@ -691,16 +691,16 @@ R: S:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
The <firstterm>Domain Relational Calculus</firstterm> The <firstterm>Domain Relational Calculus</firstterm>
(<acronym>DRC</acronym>), where variables (<acronym>DRC</acronym>), where variables
stand for components (attributes) of the tuples. stand for components (attributes) of the tuples.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
The <firstterm>Tuple Relational Calculus</firstterm> The <firstterm>Tuple Relational Calculus</firstterm>
(<acronym>TRC</acronym>), where variables stand for tuples. (<acronym>TRC</acronym>), where variables stand for tuples.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
...@@ -883,98 +883,98 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="PARAMETER">expression</replac ...@@ -883,98 +883,98 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="PARAMETER">expression</replac
<example> <example>
<title id="simple-query">Simple Query with Qualification</title> <title id="simple-query">Simple Query with Qualification</title>
<para> <para>
To retrieve all tuples from table PART where the attribute PRICE is To retrieve all tuples from table PART where the attribute PRICE is
greater than 10 we formulate the following query: greater than 10 we formulate the following query:
<programlisting> <programlisting>
SELECT * FROM PART SELECT * FROM PART
WHERE PRICE &gt; 10; WHERE PRICE &gt; 10;
</programlisting> </programlisting>
and get the table: and get the table:
<programlisting> <programlisting>
PNO | PNAME | PRICE PNO | PNAME | PRICE
-----+---------+-------- -----+---------+--------
3 | Bolt | 15 3 | Bolt | 15
4 | Cam | 25 4 | Cam | 25
</programlisting> </programlisting>
</para> </para>
<para> <para>
Using <quote>*</quote> in the <command>SELECT</command> statement Using <quote>*</quote> in the <command>SELECT</command> statement
will deliver all attributes from the table. If we want to retrieve will deliver all attributes from the table. If we want to retrieve
only the attributes PNAME and PRICE from table PART we use the only the attributes PNAME and PRICE from table PART we use the
statement: statement:
<programlisting> <programlisting>
SELECT PNAME, PRICE SELECT PNAME, PRICE
FROM PART FROM PART
WHERE PRICE &gt; 10; WHERE PRICE &gt; 10;
</programlisting> </programlisting>
In this case the result is: In this case the result is:
<programlisting> <programlisting>
PNAME | PRICE PNAME | PRICE
--------+-------- --------+--------
Bolt | 15 Bolt | 15
Cam | 25 Cam | 25
</programlisting> </programlisting>
Note that the <acronym>SQL</acronym> <command>SELECT</command> Note that the <acronym>SQL</acronym> <command>SELECT</command>
corresponds to the <quote>projection</quote> in relational algebra corresponds to the <quote>projection</quote> in relational algebra
not to the <quote>selection</quote> (see <xref linkend="rel-alg" not to the <quote>selection</quote> (see <xref linkend="rel-alg"
endterm="rel-alg"> for more details). endterm="rel-alg"> for more details).
</para> </para>
<para> <para>
The qualifications in the WHERE clause can also be logically connected The qualifications in the WHERE clause can also be logically connected
using the keywords OR, AND, and NOT: using the keywords OR, AND, and NOT:
<programlisting> <programlisting>
SELECT PNAME, PRICE SELECT PNAME, PRICE
FROM PART FROM PART
WHERE PNAME = 'Bolt' AND WHERE PNAME = 'Bolt' AND
(PRICE = 0 OR PRICE &lt;= 15); (PRICE = 0 OR PRICE &lt;= 15);
</programlisting> </programlisting>
will lead to the result: will lead to the result:
<programlisting> <programlisting>
PNAME | PRICE PNAME | PRICE
--------+-------- --------+--------
Bolt | 15 Bolt | 15
</programlisting> </programlisting>
</para> </para>
<para> <para>
Arithmetic operations can be used in the target list and in the WHERE 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 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: take two pieces of a part we could use the following query:
<programlisting> <programlisting>
SELECT PNAME, PRICE * 2 AS DOUBLE SELECT PNAME, PRICE * 2 AS DOUBLE
FROM PART FROM PART
WHERE PRICE * 2 &lt; 50; WHERE PRICE * 2 &lt; 50;
</programlisting> </programlisting>
and we get: and we get:
<programlisting> <programlisting>
PNAME | DOUBLE PNAME | DOUBLE
--------+--------- --------+---------
Screw | 20 Screw | 20
Nut | 16 Nut | 16
Bolt | 30 Bolt | 30
</programlisting> </programlisting>
Note that the word DOUBLE after the keyword AS is the new title of the 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 second column. This technique can be used for every element of the
target list to assign a new title to the resulting target list to assign a new title to the resulting
column. This new title column. This new title
is often referred to as alias. The alias cannot be used throughout the is often referred to as alias. The alias cannot be used throughout the
rest of the query. rest of the query.
</para> </para>
</example> </example>
</para> </para>
...@@ -1032,15 +1032,15 @@ SELECT S.SNAME, P.PNAME ...@@ -1032,15 +1032,15 @@ SELECT S.SNAME, P.PNAME
columns but S.SNAME and P.PNAME. columns but S.SNAME and P.PNAME.
</para> </para>
<para> <para>
Another way to perform joins is to use the SQL JOIN syntax as follows: Another way to perform joins is to use the SQL JOIN syntax as follows:
<programlisting> <programlisting>
select sname, pname from supplier select sname, pname from supplier
JOIN sells USING (sno) JOIN sells USING (sno)
JOIN part USING (pno); JOIN part USING (pno);
</programlisting> </programlisting>
giving again: giving again:
<programlisting> <programlisting>
sname | pname sname | pname
-------+------- -------+-------
Smith | Screw Smith | Screw
...@@ -1052,197 +1052,197 @@ select sname, pname from supplier ...@@ -1052,197 +1052,197 @@ select sname, pname from supplier
Jones | Cam Jones | Cam
Blake | Cam Blake | Cam
(8 rows) (8 rows)
</programlisting> </programlisting>
</para> </para>
<para> <para>
A joined table, created using JOIN syntax, is a table reference list 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, item that occurs in a FROM clause and before any WHERE, GROUP BY,
or HAVING clause. Other table references, including table names or or HAVING clause. Other table references, including table names or
other JOIN clauses, can be included in the FROM clause if separated other JOIN clauses, can be included in the FROM clause if separated
by commas. JOINed tables are logically like any other by commas. JOINed tables are logically like any other
table listed in the FROM clause. table listed in the FROM clause.
</para> </para>
<para> <para>
SQL JOINs come in two main types, CROSS JOINs (unqualified joins) SQL JOINs come in two main types, CROSS JOINs (unqualified joins)
and <firstterm>qualified JOINs</>. Qualified joins can be further and <firstterm>qualified JOINs</>. Qualified joins can be further
subdivided based on the way in which the <firstterm>join condition</> subdivided based on the way in which the <firstterm>join condition</>
is specified (ON, USING, or NATURAL) and the way in which it is is specified (ON, USING, or NATURAL) and the way in which it is
applied (INNER or OUTER join). applied (INNER or OUTER join).
</para> </para>
<variablelist> <variablelist>
<title>Join Types</title> <title>Join Types</title>
<varlistentry> <varlistentry>
<term>CROSS JOIN</term> <term>CROSS JOIN</term>
<listitem> <listitem>
<cmdsynopsis> <cmdsynopsis>
<arg choice="req"> <replaceable class="parameter">T1</replaceable> </arg> <arg choice="req"> <replaceable class="parameter">T1</replaceable> </arg>
<command> CROSS JOIN </command> <command> CROSS JOIN </command>
<arg choice="req"> <replaceable class="parameter">T2</replaceable> </arg> <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> </cmdsynopsis>
<para> <para>
A cross join takes two tables T1 and T2 having N and M rows A qualified JOIN must specify its join condition
respectively, and returns a joined table containing all by providing one (and only one) of NATURAL, ON, or
N*M possible joined rows. For each row R1 of T1, each row USING. The ON clause
R2 of T2 is joined with R1 to yield a joined table row JR takes a <replaceable>search condition</replaceable>,
consisting of all fields in R1 and R2. A CROSS JOIN is which is the same as in a WHERE clause. The USING
equivalent to an INNER JOIN ON TRUE. clause takes a comma-separated list of column names,
</para> which the joined tables must have in common, and joins
</listitem> the tables on equality of those columns. NATURAL is
</varlistentry> shorthand for a USING clause that lists all the common
column names of the two tables. A side-effect of both
<varlistentry> USING and NATURAL is that only one copy of each joined
<term>Qualified JOINs</term> column is emitted into the result table (compare the
<listitem> relational-algebra definition of JOIN, shown earlier).
</para>
<cmdsynopsis>
<arg choice="req"> <replaceable class="parameter">T1</replaceable> </arg> <!-- begin join semantics -->
<arg choice="opt"> NATURAL </arg> <variablelist>
<group choice="opt"> <varlistentry>
<arg choice="opt"> INNER </arg> <term>
<arg> <cmdsynopsis>
<group choice="req"> <arg> INNER </arg>
<arg choice="plain"> LEFT </arg> <command> JOIN </command>
<arg choice="plain"> RIGHT </arg> </cmdsynopsis>
<arg choice="plain"> FULL </arg> </term>
</group> <listitem>
<arg choice="opt"> OUTER </arg> <para>
</arg> For each row R1 of T1, the joined table has a row for each row
</group> in T2 that satisfies the join condition with R1.
<command> JOIN </command> </para>
<arg choice="req"> <replaceable class="parameter">T2</replaceable> </arg> <tip>
<group choice="req"> <para>
<arg> ON <replaceable>search condition</replaceable></arg> The words INNER and OUTER are optional for all JOINs.
<arg> USING ( <replaceable>join column list</replaceable> ) </arg> INNER is the default. LEFT, RIGHT, and FULL imply an
</group> OUTER JOIN.
</cmdsynopsis> </para>
</tip>
<para> </listitem>
A qualified JOIN must specify its join condition </varlistentry>
by providing one (and only one) of NATURAL, ON, or <varlistentry>
USING. The ON clause <term>
takes a <replaceable>search condition</replaceable>, <cmdsynopsis>
which is the same as in a WHERE clause. The USING <arg choice="plain"> LEFT </arg>
clause takes a comma-separated list of column names, <arg> OUTER </arg>
which the joined tables must have in common, and joins <command> JOIN </command>
the tables on equality of those columns. NATURAL is </cmdsynopsis>
shorthand for a USING clause that lists all the common </term>
column names of the two tables. A side-effect of both <listitem>
USING and NATURAL is that only one copy of each joined <para>
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. First, an INNER JOIN is performed.
Then, for each row in T1 that does not satisfy the join Then, for each row in T1 that does not satisfy the join
condition with any row in T2, an additional joined row is condition with any row in T2, an additional joined row is
returned with null fields in the columns from T2. returned with null fields in the columns from T2.
</para> </para>
<tip> <tip>
<para> <para>
The joined table unconditionally has a row for each row in T1. The joined table unconditionally has a row for each row in T1.
</para> </para>
</tip> </tip>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<cmdsynopsis> <cmdsynopsis>
<arg choice="plain"> RIGHT </arg> <arg choice="plain"> RIGHT </arg>
<arg> OUTER </arg> <arg> OUTER </arg>
<command> JOIN </command> <command> JOIN </command>
</cmdsynopsis> </cmdsynopsis>
</term> </term>
<listitem> <listitem>
<para> <para>
First, an INNER JOIN is performed. First, an INNER JOIN is performed.
Then, for each row in T2 that does not satisfy the join Then, for each row in T2 that does not satisfy the join
condition with any row in T1, an additional joined row is condition with any row in T1, an additional joined row is
returned with null fields in the columns from T1. returned with null fields in the columns from T1.
</para> </para>
<tip> <tip>
<para> <para>
The joined table unconditionally has a row for each row in T2. The joined table unconditionally has a row for each row in T2.
</para> </para>
</tip> </tip>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<cmdsynopsis> <cmdsynopsis>
<arg choice="plain"> FULL </arg> <arg choice="plain"> FULL </arg>
<arg> OUTER </arg> <arg> OUTER </arg>
<command> JOIN </command> <command> JOIN </command>
</cmdsynopsis> </cmdsynopsis>
</term> </term>
<listitem> <listitem>
<para> <para>
First, an INNER JOIN is performed. First, an INNER JOIN is performed.
Then, for each row in T1 that does not satisfy the join Then, for each row in T1 that does not satisfy the join
condition with any row in T2, an additional joined row is condition with any row in T2, an additional joined row is
returned with null fields in the columns from T2. returned with null fields in the columns from T2.
Also, for each row in T2 that does not satisfy the join Also, for each row in T2 that does not satisfy the join
condition with any row in T1, an additional joined row is condition with any row in T1, an additional joined row is
returned with null fields in the columns from T1. returned with null fields in the columns from T1.
</para> </para>
<tip> <tip>
<para> <para>
The joined table unconditionally has a row for every row of T1 The joined table unconditionally has a row for every row of T1
and a row for every row of T2. and a row for every row of T2.
</para> </para>
</tip> </tip>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
<!-- end join semantics --> <!-- end join semantics -->
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
<para> <para>
JOINs of all types can be chained together or nested where either or both of JOINs of all types can be chained together or nested where either or both of
<replaceable class="parameter">T1</replaceable> and <replaceable class="parameter">T1</replaceable> and
<replaceable class="parameter">T2</replaceable> can be JOINed tables. <replaceable class="parameter">T2</replaceable> can be JOINed tables.
Parenthesis can be used around JOIN clauses to control the order Parenthesis can be used around JOIN clauses to control the order
of JOINs which are otherwise processed left to right. of JOINs which are otherwise processed left to right.
</para> </para>
</sect3> </sect3>
...@@ -1264,41 +1264,41 @@ select sname, pname from supplier ...@@ -1264,41 +1264,41 @@ select sname, pname from supplier
<title id="aggregates-example">Aggregates</title> <title id="aggregates-example">Aggregates</title>
<para> <para>
If we want to know the average cost of all parts in table PART we use If we want to know the average cost of all parts in table PART we use
the following query: the following query:
<programlisting> <programlisting>
SELECT AVG(PRICE) AS AVG_PRICE SELECT AVG(PRICE) AS AVG_PRICE
FROM PART; FROM PART;
</programlisting> </programlisting>
</para> </para>
<para> <para>
The result is: The result is:
<programlisting> <programlisting>
AVG_PRICE AVG_PRICE
----------- -----------
14.5 14.5
</programlisting> </programlisting>
</para> </para>
<para> <para>
If we want to know how many parts are defined in table PART we use If we want to know how many parts are defined in table PART we use
the statement: the statement:
<programlisting> <programlisting>
SELECT COUNT(PNO) SELECT COUNT(PNO)
FROM PART; FROM PART;
</programlisting> </programlisting>
and get: and get:
<programlisting> <programlisting>
COUNT COUNT
------- -------
4 4
</programlisting> </programlisting>
</para> </para>
</example> </example>
...@@ -1332,34 +1332,34 @@ SELECT COUNT(PNO) ...@@ -1332,34 +1332,34 @@ SELECT COUNT(PNO)
<example> <example>
<title id="aggregates-groupby">Aggregates</title> <title id="aggregates-groupby">Aggregates</title>
<para> <para>
If we want to know how many parts are sold by every supplier we If we want to know how many parts are sold by every supplier we
formulate the query: formulate the query:
<programlisting> <programlisting>
SELECT S.SNO, S.SNAME, COUNT(SE.PNO) SELECT S.SNO, S.SNAME, COUNT(SE.PNO)
FROM SUPPLIER S, SELLS SE FROM SUPPLIER S, SELLS SE
WHERE S.SNO = SE.SNO WHERE S.SNO = SE.SNO
GROUP BY S.SNO, S.SNAME; GROUP BY S.SNO, S.SNAME;
</programlisting> </programlisting>
and get: and get:
<programlisting> <programlisting>
SNO | SNAME | COUNT SNO | SNAME | COUNT
-----+-------+------- -----+-------+-------
1 | Smith | 2 1 | Smith | 2
2 | Jones | 1 2 | Jones | 1
3 | Adams | 2 3 | Adams | 2
4 | Blake | 3 4 | Blake | 3
</programlisting> </programlisting>
</para> </para>
<para> <para>
Now let's have a look of what is happening here. Now let's have a look of what is happening here.
First the join of the First the join of the
tables SUPPLIER and SELLS is derived: tables SUPPLIER and SELLS is derived:
<programlisting> <programlisting>
S.SNO | S.SNAME | SE.PNO S.SNO | S.SNAME | SE.PNO
-------+---------+-------- -------+---------+--------
1 | Smith | 1 1 | Smith | 1
...@@ -1370,14 +1370,14 @@ SELECT S.SNO, S.SNAME, COUNT(SE.PNO) ...@@ -1370,14 +1370,14 @@ SELECT S.SNO, S.SNAME, COUNT(SE.PNO)
4 | Blake | 2 4 | Blake | 2
4 | Blake | 3 4 | Blake | 3
4 | Blake | 4 4 | Blake | 4
</programlisting> </programlisting>
</para> </para>
<para> <para>
Next we partition the tuples into groups by putting all tuples Next we partition the tuples into groups by putting all tuples
together that agree on both attributes S.SNO and S.SNAME: together that agree on both attributes S.SNO and S.SNAME:
<programlisting> <programlisting>
S.SNO | S.SNAME | SE.PNO S.SNO | S.SNAME | SE.PNO
-------+---------+-------- -------+---------+--------
1 | Smith | 1 1 | Smith | 1
...@@ -1391,13 +1391,13 @@ SELECT S.SNO, S.SNAME, COUNT(SE.PNO) ...@@ -1391,13 +1391,13 @@ SELECT S.SNO, S.SNAME, COUNT(SE.PNO)
4 | Blake | 2 4 | Blake | 2
| 3 | 3
| 4 | 4
</programlisting> </programlisting>
</para> </para>
<para> <para>
In our example we got four groups and now we can apply the aggregate 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 function COUNT to every group leading to the final result of the query
given above. given above.
</para> </para>
</example> </example>
</para> </para>
...@@ -1439,26 +1439,26 @@ SELECT S.SNO, S.SNAME, COUNT(SE.PNO) ...@@ -1439,26 +1439,26 @@ SELECT S.SNO, S.SNAME, COUNT(SE.PNO)
<title id="having-example">Having</title> <title id="having-example">Having</title>
<para> <para>
If we want only those suppliers selling more than one part we use the If we want only those suppliers selling more than one part we use the
query: query:
<programlisting> <programlisting>
SELECT S.SNO, S.SNAME, COUNT(SE.PNO) SELECT S.SNO, S.SNAME, COUNT(SE.PNO)
FROM SUPPLIER S, SELLS SE FROM SUPPLIER S, SELLS SE
WHERE S.SNO = SE.SNO WHERE S.SNO = SE.SNO
GROUP BY S.SNO, S.SNAME GROUP BY S.SNO, S.SNAME
HAVING COUNT(SE.PNO) &gt; 1; HAVING COUNT(SE.PNO) &gt; 1;
</programlisting> </programlisting>
and get: and get:
<programlisting> <programlisting>
SNO | SNAME | COUNT SNO | SNAME | COUNT
-----+-------+------- -----+-------+-------
1 | Smith | 2 1 | Smith | 2
3 | Adams | 2 3 | Adams | 2
4 | Blake | 3 4 | Blake | 3
</programlisting> </programlisting>
</para> </para>
</example> </example>
</para> </para>
...@@ -1478,64 +1478,64 @@ SELECT S.SNO, S.SNAME, COUNT(SE.PNO) ...@@ -1478,64 +1478,64 @@ SELECT S.SNO, S.SNAME, COUNT(SE.PNO)
<title id="subselect-example">Subselect</title> <title id="subselect-example">Subselect</title>
<para> <para>
If we want to know all parts having a greater price than the part If we want to know all parts having a greater price than the part
named 'Screw' we use the query: named 'Screw' we use the query:
<programlisting> <programlisting>
SELECT * SELECT *
FROM PART FROM PART
WHERE PRICE &gt; (SELECT PRICE FROM PART WHERE PRICE &gt; (SELECT PRICE FROM PART
WHERE PNAME='Screw'); WHERE PNAME='Screw');
</programlisting> </programlisting>
</para> </para>
<para> <para>
The result is: The result is:
<programlisting> <programlisting>
PNO | PNAME | PRICE PNO | PNAME | PRICE
-----+---------+-------- -----+---------+--------
3 | Bolt | 15 3 | Bolt | 15
4 | Cam | 25 4 | Cam | 25
</programlisting> </programlisting>
</para> </para>
<para> <para>
When we look at the above query we can see the keyword When we look at the above query we can see the keyword
<command>SELECT</command> two times. The first one at the <command>SELECT</command> two times. The first one at the
beginning of the query - we will refer to it as outer beginning of the query - we will refer to it as outer
<command>SELECT</command> - and the one in the WHERE clause which <command>SELECT</command> - and the one in the WHERE clause which
begins a nested query - we will refer to it as inner begins a nested query - we will refer to it as inner
<command>SELECT</command>. For every tuple of the outer <command>SELECT</command>. For every tuple of the outer
<command>SELECT</command> the inner <command>SELECT</command> has <command>SELECT</command> the inner <command>SELECT</command> has
to be evaluated. After every evaluation we know the price of the 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 named 'Screw' and we can check if the price of the actual
tuple is greater. (Actually, in this example the inner query need tuple is greater. (Actually, in this example the inner query need
only be evaluated once, since it does not depend on the state of only be evaluated once, since it does not depend on the state of
the outer query.) the outer query.)
</para> </para>
<para> <para>
If we want to know all suppliers that do not sell any part 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: (e.g. to be able to remove these suppliers from the database) we use:
<programlisting> <programlisting>
SELECT * SELECT *
FROM SUPPLIER S FROM SUPPLIER S
WHERE NOT EXISTS WHERE NOT EXISTS
(SELECT * FROM SELLS SE (SELECT * FROM SELLS SE
WHERE SE.SNO = S.SNO); WHERE SE.SNO = S.SNO);
</programlisting> </programlisting>
</para> </para>
<para> <para>
In our example the result will be empty because every supplier 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 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> within the WHERE clause of the inner
<command>SELECT</command>. Here the subquery must be evaluated <command>SELECT</command>. Here the subquery must be evaluated
afresh for each tuple from the outer query, i.e. the value for 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 S.SNO is always taken from the current tuple of the outer
<command>SELECT</command>. <command>SELECT</command>.
</para> </para>
</example> </example>
</para> </para>
...@@ -1557,19 +1557,19 @@ SELECT * ...@@ -1557,19 +1557,19 @@ SELECT *
<para> <para>
If we want to know the highest average part price among all our If we want to know the highest average part price among all our
suppliers, we cannot write MAX(AVG(PRICE)), but we can write: suppliers, we cannot write MAX(AVG(PRICE)), but we can write:
<programlisting> <programlisting>
SELECT MAX(subtable.avgprice) SELECT MAX(subtable.avgprice)
FROM (SELECT AVG(P.PRICE) AS avgprice FROM (SELECT AVG(P.PRICE) AS avgprice
FROM SUPPLIER S, PART P, SELLS SE FROM SUPPLIER S, PART P, SELLS SE
WHERE S.SNO = SE.SNO AND WHERE S.SNO = SE.SNO AND
P.PNO = SE.PNO P.PNO = SE.PNO
GROUP BY S.SNO) subtable; GROUP BY S.SNO) subtable;
</programlisting> </programlisting>
The subquery returns one row per supplier (because of its GROUP BY) The subquery returns one row per supplier (because of its GROUP BY)
and then we aggregate over those rows in the outer query. and then we aggregate over those rows in the outer query.
</para> </para>
</example> </example>
</para> </para>
...@@ -1586,9 +1586,9 @@ SELECT MAX(subtable.avgprice) ...@@ -1586,9 +1586,9 @@ SELECT MAX(subtable.avgprice)
<title id="union-example">Union, Intersect, Except</title> <title id="union-example">Union, Intersect, Except</title>
<para> <para>
The following query is an example for UNION: The following query is an example for UNION:
<programlisting> <programlisting>
SELECT S.SNO, S.SNAME, S.CITY SELECT S.SNO, S.SNAME, S.CITY
FROM SUPPLIER S FROM SUPPLIER S
WHERE S.SNAME = 'Jones' WHERE S.SNAME = 'Jones'
...@@ -1596,22 +1596,22 @@ UNION ...@@ -1596,22 +1596,22 @@ UNION
SELECT S.SNO, S.SNAME, S.CITY SELECT S.SNO, S.SNAME, S.CITY
FROM SUPPLIER S FROM SUPPLIER S
WHERE S.SNAME = 'Adams'; WHERE S.SNAME = 'Adams';
</programlisting> </programlisting>
gives the result: gives the result:
<programlisting> <programlisting>
SNO | SNAME | CITY SNO | SNAME | CITY
-----+-------+-------- -----+-------+--------
2 | Jones | Paris 2 | Jones | Paris
3 | Adams | Vienna 3 | Adams | Vienna
</programlisting> </programlisting>
</para> </para>
<para> <para>
Here is an example for INTERSECT: Here is an example for INTERSECT:
<programlisting> <programlisting>
SELECT S.SNO, S.SNAME, S.CITY SELECT S.SNO, S.SNAME, S.CITY
FROM SUPPLIER S FROM SUPPLIER S
WHERE S.SNO &gt; 1 WHERE S.SNO &gt; 1
...@@ -1619,23 +1619,23 @@ INTERSECT ...@@ -1619,23 +1619,23 @@ INTERSECT
SELECT S.SNO, S.SNAME, S.CITY SELECT S.SNO, S.SNAME, S.CITY
FROM SUPPLIER S FROM SUPPLIER S
WHERE S.SNO &lt; 3; WHERE S.SNO &lt; 3;
</programlisting> </programlisting>
gives the result: gives the result:
<programlisting> <programlisting>
SNO | SNAME | CITY SNO | SNAME | CITY
-----+-------+-------- -----+-------+--------
2 | Jones | Paris 2 | Jones | Paris
</programlisting> </programlisting>
The only tuple returned by both parts of the query is the one having SNO=2. The only tuple returned by both parts of the query is the one having SNO=2.
</para> </para>
<para> <para>
Finally an example for EXCEPT: Finally an example for EXCEPT:
<programlisting> <programlisting>
SELECT S.SNO, S.SNAME, S.CITY SELECT S.SNO, S.SNAME, S.CITY
FROM SUPPLIER S FROM SUPPLIER S
WHERE S.SNO &gt; 1 WHERE S.SNO &gt; 1
...@@ -1643,16 +1643,16 @@ EXCEPT ...@@ -1643,16 +1643,16 @@ EXCEPT
SELECT S.SNO, S.SNAME, S.CITY SELECT S.SNO, S.SNAME, S.CITY
FROM SUPPLIER S FROM SUPPLIER S
WHERE S.SNO &gt; 3; WHERE S.SNO &gt; 3;
</programlisting> </programlisting>
gives the result: gives the result:
<programlisting> <programlisting>
SNO | SNAME | CITY SNO | SNAME | CITY
-----+-------+-------- -----+-------+--------
2 | Jones | Paris 2 | Jones | Paris
3 | Adams | Vienna 3 | Adams | Vienna
</programlisting> </programlisting>
</para> </para>
</example> </example>
</para> </para>
...@@ -1686,11 +1686,11 @@ CREATE TABLE <replaceable class="parameter">table_name</replaceable> ...@@ -1686,11 +1686,11 @@ CREATE TABLE <replaceable class="parameter">table_name</replaceable>
<title id="table-create">Table Creation</title> <title id="table-create">Table Creation</title>
<para> <para>
To create the tables defined in To create the tables defined in
<xref linkend="supplier-fig" endterm="supplier-fig"> the <xref linkend="supplier-fig" endterm="supplier-fig"> the
following <acronym>SQL</acronym> statements are used: following <acronym>SQL</acronym> statements are used:
<programlisting> <programlisting>
CREATE TABLE SUPPLIER CREATE TABLE SUPPLIER
(SNO INTEGER, (SNO INTEGER,
SNAME VARCHAR(20), SNAME VARCHAR(20),
...@@ -1708,7 +1708,7 @@ CREATE TABLE PART ...@@ -1708,7 +1708,7 @@ CREATE TABLE PART
CREATE TABLE SELLS CREATE TABLE SELLS
(SNO INTEGER, (SNO INTEGER,
PNO INTEGER); PNO INTEGER);
</programlisting> </programlisting>
</para> </para>
</example> </example>
</para> </para>
...@@ -1723,50 +1723,50 @@ CREATE TABLE SELLS ...@@ -1723,50 +1723,50 @@ CREATE TABLE SELLS
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
INTEGER: signed fullword binary integer (31 bits precision). INTEGER: signed fullword binary integer (31 bits precision).
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
SMALLINT: signed halfword binary integer (15 bits precision). SMALLINT: signed halfword binary integer (15 bits precision).
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
DECIMAL (<replaceable class="parameter">p</replaceable>[,<replaceable class="parameter">q</replaceable>]): DECIMAL (<replaceable class="parameter">p</replaceable>[,<replaceable class="parameter">q</replaceable>]):
signed packed decimal number of up to signed packed decimal number of up to
<replaceable class="parameter">p</replaceable> <replaceable class="parameter">p</replaceable>
digits, with digits, with
<replaceable class="parameter">q</replaceable> <replaceable class="parameter">q</replaceable>
digits to the right of the decimal point. digits to the right of the decimal point.
If <replaceable class="parameter">q</replaceable> If <replaceable class="parameter">q</replaceable>
is omitted it is assumed to be 0. is omitted it is assumed to be 0.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
FLOAT: signed doubleword floating point number. FLOAT: signed doubleword floating point number.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
VARCHAR(<replaceable class="parameter">n</replaceable>): VARCHAR(<replaceable class="parameter">n</replaceable>):
varying length character string of maximum length varying length character string of maximum length
<replaceable class="parameter">n</replaceable>. <replaceable class="parameter">n</replaceable>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
CHAR(<replaceable class="parameter">n</replaceable>): CHAR(<replaceable class="parameter">n</replaceable>):
fixed length character string of length fixed length character string of length
<replaceable class="parameter">n</replaceable>. <replaceable class="parameter">n</replaceable>.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
...@@ -1802,8 +1802,8 @@ CREATE INDEX <replaceable class="parameter">index_name</replaceable> ...@@ -1802,8 +1802,8 @@ CREATE INDEX <replaceable class="parameter">index_name</replaceable>
<title id="index-create">Create Index</title> <title id="index-create">Create Index</title>
<para> <para>
To create an index named I on attribute SNAME of relation SUPPLIER To create an index named I on attribute SNAME of relation SUPPLIER
we use the following statement: we use the following statement:
<programlisting> <programlisting>
CREATE INDEX I ON SUPPLIER (SNAME); CREATE INDEX I ON SUPPLIER (SNAME);
...@@ -1811,11 +1811,11 @@ CREATE INDEX I ON SUPPLIER (SNAME); ...@@ -1811,11 +1811,11 @@ CREATE INDEX I ON SUPPLIER (SNAME);
</para> </para>
<para> <para>
The created index is maintained automatically, i.e. whenever a new The created index is maintained automatically, i.e. whenever a new
tuple is inserted into the relation SUPPLIER the index I is tuple is inserted into the relation SUPPLIER the index I is
adapted. Note that the only changes a user can perceive when an adapted. Note that the only changes a user can perceive when an
index is present are increased speed for <command>SELECT</command> index is present are increased speed for <command>SELECT</command>
and decreases in speed of updates. and decreases in speed of updates.
</para> </para>
</example> </example>
</para> </para>
...@@ -2089,20 +2089,20 @@ DELETE FROM SUPPLIER ...@@ -2089,20 +2089,20 @@ DELETE FROM SUPPLIER
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
There are queries that cannot be formulated using pure <acronym>SQL</acronym> 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 (i.e. recursive queries). To be able to perform such queries we need a
host language with a greater expressive power than host language with a greater expressive power than
<acronym>SQL</acronym>. <acronym>SQL</acronym>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
We simply want to access a database from some application that We simply want to access a database from some application that
is written in the host language (e.g. a ticket reservation system is written in the host language (e.g. a ticket reservation system
with a graphical user interface is written in C and the information 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 about which tickets are still left is stored in a database that can be
accessed using embedded <acronym>SQL</acronym>). accessed using embedded <acronym>SQL</acronym>).
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment