Description of table expressions, including join syntax, from Robert B.
authorPeter Eisentraut
Sun, 21 Jan 2001 22:02:01 +0000 (22:02 +0000)
committerPeter Eisentraut
Sun, 21 Jan 2001 22:02:01 +0000 (22:02 +0000)
Easter , heavily massaged by me.  Also cleaned up
value expressions a bit.

doc/src/sgml/func.sgml
doc/src/sgml/syntax.sgml

index 4ea4881f81b5c73ad6a5403510b452af8cc1846c..cf4ac7f7ac7055965c9c0abde3b614956c2edc6b 100644 (file)
@@ -1,4 +1,4 @@
-
+
 
 
  Functions and Operators
   other implementations.
  
 
+
+  Logical Operators
+
+  
+   The usual logical operators are available:
+
+   
+    AND
+    OR
+    NOT
+   
+
+   SQL uses a three-valued boolean logic where NULL represents
+   unknown.  Observe the following truth tables:
+
+   
+    
+     
+      
+       a
+       b
+       a AND b
+       a OR b
+      
+     
+
+     
+      
+       TRUE
+       TRUE
+       TRUE
+       TRUE
+      
+
+      
+       TRUE
+       FALSE
+       FALSE
+       TRUE
+      
+
+      
+       TRUE
+       NULL
+       NULL
+       TRUE
+      
+
+      
+       FALSE
+       FALSE
+       FALSE
+       FALSE
+      
+
+      
+       FALSE
+       NULL
+       FALSE
+       NULL
+      
+     
+    
+   
+
+   
+    
+     
+      
+       a
+       NOT a
+      
+     
+
+     
+      
+       TRUE
+       FALSE
+      
+
+      
+       FALSE
+       TRUE
+      
+
+      
+       NULL
+       NULL
+      
+     
+    
+   
+  
+
  
   Comparison Operators
 
    < operator to compare a boolean with
    3).
   
+
+  
+   To check whether a value is or is not NULL, use the constructs
+
+expression IS NULL
+expression IS NOT NULL
+
+   Do not use
+   expression = NULL
+   because NULL is not equal to NULL.  (NULL represents
+   an unknown value, so it is not known whether two unknown values are
+   equal.)  Postgres implicitly converts
+   = NULL clauses to IS NULL to
+   allow some broken client applications (such as
+   Microsoft Access) to work, but this may
+   be discontinued in a future release.
+  
  
 
 
index 918ff103dd99cb1a7977f0319cfdcb2ed025ab24..f994cbe0a07ac8bbbf6d438417c4dd439a9f882d 100644 (file)
@@ -1,5 +1,5 @@
 
 
 
@@ -17,10 +17,10 @@ $Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.35 2001/01/13 23:58:55 pete
   
    SQL input consists of a sequence of
    commands.  A command is composed of a
-   sequence of tokenswhich depend on the
-   syntax of the particular command, terminated by a semicolon
-   (;).  The end of the input stream also terminates a
-   command.
+   sequence of tokensterminated by a
+   semicolon (;).  The end of the input stream also
+   terminates a command.  Which tokens are valid depends on the syntax
+   of the particular command.
   
 
   
@@ -41,7 +41,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.35 2001/01/13 23:58:55 pete
 
   
    
-    For example, the following is (lexically) valid SQL input:
+    For example, the following is (syntactically) valid SQL input:
 
 SELECT * FROM MY_TABLE;
 UPDATE MY_TABLE SET A = 5;
@@ -93,7 +93,7 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there');
     key word can be letters, digits
     (0-9), or underscores,
     although the SQL standard will not define a key word that contains
-    digits or start or ends with an underscore.
+    digits or starts or ends with an underscore.
    
 
    
@@ -181,7 +181,7 @@ UPDATE "my_table" SET "a" = 5;
     constants are discussed afterwards.
    
 
-   
+    id="sql-syntax-strings">
     String Constants
 
     
@@ -651,251 +651,244 @@ CAST ( 'string' AS type )
      Transaction and command identifiers are 32 bit quantities.
     
 
-    
-     A column can be referenced in the form:
-
-
-corelation.columnname `['subscript`]'
-
+  
 
-     corelation is either the name of a
-     table, an alias for a table defined by means of a FROM clause, or
-     the keyword NEW or OLD.
-     (NEW and OLD can only appear in the action portion of a rule,
-     while other corelation names can be used in any SQL statement.)
-     The corelation name can be omitted if the column name is unique
-     across all the tables being used in the current query.  If
-     column is of an array type, then the
-     optional subscript selects a specific
-     element in the array.  If no subscript is provided, then the
-     whole array is selected.  Refer to the description of the
-     particular commands in the PostgreSQL Reference
-     Manual for the allowed syntax in each case.
-    
 
-  
+  Value Expressions
 
-  
-   Expressions
+  
+   Value expressions are used in a variety of syntactic contexts, such
+   as in the target list of the SELECT command, as
+   new column values in INSERT or
+   UPDATE, or in search conditions in a number of
+   commands.  The result of a value expression is sometimes called a
+   scalar, to distinguish it from the result of
+   a table expression (which is a table).  Value expressions are
+   therefore also called scalar expressions (or
+   even simply expressions).  The expression
+   syntax allows the calculation of values from primitive parts using
+   arithmetic, logical, set, and other operations.
+  
 
-   
-    SQL92 allows expressions
-    to transform data in tables. Expressions may contain operators
-    and functions.
-   
+  
+   A value expression is one of the following:
 
-   
-    An expression is one of the following:
+   
+    
+     
+      A constant or literal value; see .
+     
+    
 
-    
-     constant
-     column
-     expression binary_operator expression
-     expression right_unary_operator
-     left_unary_operator expression
-     expression )
-     parameter
-     functional expression
-     aggregate expression
-    
-   
+    
+     
+      A column reference
+     
+    
 
-   
-    We have already discussed constants and columns.  The three kinds of
-    operator expressions indicate respectively binary (infix), right-unary
-    (suffix) and left-unary (prefix) operators.  The following sections
-    discuss the remaining options.
-   
+    
+     
+      An operator invocation:
+      
+       expression operator expression (binary infix operator)
+       expression operator (unary postfix operator)
+       operator expression (unary prefix operator)
+      
+      where operator follows the syntax
+      rules of  or is one of the
+      tokens ANDOR, and
+      NOT.  What particular operators exist and whether
+      they are unary or binary depends on what operators have been
+      defined by the system or the user.  
+      describes the built-in operators.
+     
+    
 
-   
-    Parameters
+    
+     
+expression )
+      Parentheses are used to group subexpressions and override precedence.
+     
+    
 
-    
-     A parameter
-     is used to indicate a parameter in a SQL function.  Typically this
-     is used in SQL function definition statements.  The form of a
-     parameter is:
-
-     
-$number
-     
-    
+    
+     
+      A positional parameter reference, in the body of a function declaration.
+     
+    
 
-    
-     For example, consider the definition of a function,
-     dept, as
-
-     
-CREATE FUNCTION dept (name)
-   RETURNS dept
-   AS 'select * from dept where name = $1'
-   LANGUAGE 'sql';
-     
-    
-   
+    
+     
+      A function call
+     
+    
 
-   
-    Functional Expressions
+    
+     
+      An aggregate expression
+     
+    
 
-    
-     A functional expression
-     is the name of a legal SQL function, followed by its argument list
-     enclosed in parentheses:
+    
+     
+      A scalar subquery.  This is an ordinary
+      SELECT in parenthesis that returns exactly one
+      row with one column.  It is an error to use a subquery that
+      returns more than one row or more than one column in the context
+      of a value expression.
+     
+    
+   
+  
 
-     
-function (expression [, expression ... ] )
-     
-    
+  
+   In addition to this list, there are a number of contructs that can
+   be classified as an expression but do not follow any general syntax
+   rules.  These generally have the semantics of a function or
+   operator and are explained in the appropriate location in 
+   linkend="functions">.  An example is the IS NULL
+   clause.
+  
 
-    
-     For example, the following computes the square root of an employee
-     salary:
+  
+   We have already discussed constants in 
+   linkend="sql-syntax-constants">.  The following sections discuss
+   the remaining options.
+  
 
-     
-sqrt(emp.salary)
-     
-    
-   
+  
+   Column References
 
-   
-    Aggregate Expressions
+   
+    A column can be referenced in the form:
+
+corelation.columnname `['subscript`]'
+
 
-    
-     An aggregate expression represents the application
-     of an aggregate function across the rows selected by a query.
-     An aggregate function reduces multiple inputs to a single output value,
-     such as the sum or average of the inputs.
-     The syntax of an aggregate expression is one of the following:
+    corelation is either the name of a
+    table, an alias for a table defined by means of a FROM clause, or
+    the keyword NEW or OLD.
+    (NEW and OLD can only appear in the action portion of a rule,
+    while other corelation names can be used in any SQL statement.)
+    The corelation name can be omitted if the column name is unique
+    across all the tables being used in the current query.  If
+    column is of an array type, then the
+    optional subscript selects a specific
+    element in the array.  If no subscript is provided, then the whole
+    array is selected.  Refer to the description of the particular
+    commands in the PostgreSQL Reference Manual
+    for the allowed syntax in each case.
+   
+  
 
-    
-     aggregate_name (expression)
-     aggregate_name (ALL expression)
-     aggregate_name (DISTINCT expression)
-     aggregate_name ( * )
-    
+  
+   Positional Parameters
 
-     where aggregate_name is a previously defined
-     aggregate, and expression is any expression
-     that doesn't itself contain an aggregate expression.
-    
+   
+    A positional parameter reference is used to indicate a parameter
+    in an SQL function.  Typically this is used in SQL function
+    definition statements.  The form of a parameter is:
+
+$number
+
+   
 
-    
-     The first form of aggregate expression invokes the aggregate across all
-     input rows for which the given expression yields a non-null value.
-     The second form is the same as the first, since ALL is the default.
-     The third form invokes the aggregate for all distinct non-null values
-     of the expression found in the input rows.  The last form invokes the
-     aggregate once for each input row regardless of null or non-null values;
-     since no particular input value is specified, it is generally only useful
-     for the count() aggregate.
-    
+   
+    For example, consider the definition of a function,
+    dept, as
 
-    
-      For example, count(*) yields the total number of input rows;
-      count(f1) yields the number of input rows in which f1 is non-null;
-      count(distinct f1) yields the number of distinct non-null values of f1.
-    
-   
+
+CREATE FUNCTION dept (text) RETURNS dept
+  AS 'select * from dept where name = $1'
+  LANGUAGE 'sql';
+
 
-   
-    Target List
+    Here the $1 will be replaced by the first
+    function argument when the function is invoked.
+   
+  
 
-    
-     A target list
-     is a comma-separated list of one or more elements, each
-     of which must be of the form:
-
-     
-expression [ AS result_attname ]
-     
-
-     where result_attname
-     is the name to be assigned to the created column.  If 
-     result_attname
-     is not present, then Postgres selects a
-     default name based on the contents of expression.
-     If expression is a simple attribute reference
-     then the default name will be the same as that attribute's name, but
-     otherwise the implementation is free to assign any default name.
-    
-   
+  
+   Function Calls
 
-   
-    Qualification
+   
+    The syntax for a function call is the name of a legal function
+    (subject to the syntax rules for identifiers of 
+    linkend="sql-syntax-identifiers"> , followed by its argument list
+    enclosed in parentheses:
 
-    
-     A qualification
-     consists of any number of clauses connected by the logical operators:
+
+function (expression expression ...  )
+
+   
 
-     
-      NOT
-      AND
-      OR
-     
+   
+    For example, the following computes the square root of 2:
+
+sqrt(2)
+
+   
 
-     A clause is an expression
-     that evaluates to a boolean over a set of instances.
-    
-   
+   
+    The list of built-in functions is in .
+    Other functions may be added by the user.
+   
+  
 
-   >
-    From List</span>
+  >
+   Aggregate Expressions</span>
 
-    
-     The from list
-     is a comma-separated list of from-expressions.
-     The simplest possibility for a from-expression is:
-
-     
-table_reference [ [ AS ] alias ]
-     
-
-     where table_reference is of the form
-
-     
-[ ONLY ] table_name [ * ]
-     
-
-     The from-expression defines an instance variable that ranges over the
-     rows of the specified table.  The instance variable's name is either
-     the table name, or the alias if one is given.
-     Ordinarily, if the table has child tables then the instance variable
-     will range over all rows in the inheritance hierarchy starting with
-     the specified table.  If ONLY is specified then
-     child tables are not included.  A trailing asterisk *
-     can be written to specifically indicate that child tables are included
-     (ONLY and * are mutually
-     exclusive).
-    
+   
+    An aggregate expression represents the
+    application of an aggregate function across the rows selected by a
+    query.  An aggregate function reduces multiple inputs to a single
+    output value, such as the sum or average of the inputs.  The
+    syntax of an aggregate expression is one of the following:
 
-    
-     A from-expression can also be a sub-query:
+    
+     aggregate_name (expression)
+     aggregate_name (ALL expression)
+     aggregate_name (DISTINCT expression)
+     aggregate_name ( * )
+    
 
-     
-( select-statement ) [ AS ] alias
-     
+    where aggregate_name is a previously
+    defined aggregate, and expression is
+    any expression that does not itself contain an aggregate
+    expression.
+   
 
-     Here, the effect is as though the SELECT were executed and its results
-     stored in a temporary table, which then becomes available as an instance
-     variable under the given alias.
-    
+   
+    The first form of aggregate expression invokes the aggregate
+    across all input rows for which the given expression yields a
+    non-NULL value.  The second form is the same as the first, since
+    ALL is the default.  The third form invokes the
+    aggregate for all distinct non-NULL values of the expression found
+    in the input rows.  The last form invokes the aggregate once for
+    each input row regardless of NULL or non-NULL values; since no
+    particular input value is specified, it is generally only useful
+    for the count() aggregate function.
+   
 
-    
-     Finally, a from-expression can be built up from simpler from-expressions
-     using JOIN clauses:
+   
+    For example, count(*) yields the total number
+    of input rows; count(f1) yields the number of
+    input rows in which f1 is non-NULL;
+    count(distinct f1) yields the number of
+    distinct non-NULL values of f1.
+   
 
-     
-from_expression [ NATURAL ] join_type from_expression
-    [ ON join_condition | USING ( join_column_list ) ]
-     
+   
+    The predefined aggregate functions are described in 
+    linkend="functions-aggregate">.
+   
+  
 
-     This syntax allows specification of outer joins.
-     For details see the reference page for SELECT.
-    
-   
 
 
-  2 id="sql-precedence">
+  1 id="sql-precedence">
    Lexical Precedence
 
    
@@ -919,7 +912,7 @@ SELECT (5 &) ~ 6;
    
 
    
-    Operator <span class="marked">Ordering (decreasing precedence</span>)
+    Operator <span class="marked">Precedence (decreasing</span>)
 
     
      
@@ -1062,10 +1055,529 @@ SELECT (5 &) ~ 6;
     the same precedence as the built-in + operator, no
     matter what yours does.
    
+  
+
+
+  Table Expressions
+
+  
+   A table expression specifies a table.  The
+   table expression contains a FROM clause that is optionally followed
+   by WHERE, GROUP BY, and HAVING clauses.  Trivial table expressions
+   simply refer to a table on disk, a so-called base table, but more
+   complex expressions can be used to modify or combine base tables in
+   various ways.
+  
+
+  
+   The general syntax of the SELECT command is
+
+SELECT select_list table_expression
+
+
+   The select_list is a comma separated
+   list of value expressions as defined in
+    that specify the derived columns
+   of the query output table.  Column names in the derived table that
+   is the result of the table_expression
+   can be used in the value expressions of
+   the select_list.
+  
+
+  
+   The WHERE, GROUP BY, and HAVING clauses in the table expression
+   specify a pipeline of successive transformations performed on the
+   table derived in the FROM clause.  The final transformed table that
+   is derived provides the input rows used to derive output rows as
+   specified by the select list of derived column value expressions.
+  
+   
+  
+   FROM clause
+   
+    The FROM clause derives a table from one or more other tables
+    given in a comma-separated table reference list.
+
+FROM table_reference table_reference , ...
+
+
+    A table reference may be a table name or a derived table such as a
+    subquery, a table join, or complex combinations of these.  If more
+    than one table reference is listed in the FROM clause they are
+    CROSS JOINed (see below) to form the derived table that may then
+    be subject to transformations by the WHERE, GROUP BY, and HAVING
+    clauses and is finally the result of the overall table expression.
+   
+
+   
+    If a table reference is a simple table name and it is the
+    supertable in a table inheritance hierarchy, rows of the table
+    include rows from all of its subtable successors unless the
+    keyword ONLY precedes the table name.
+   
+
+   
+    Joined Tables
+
+    
+     A joined table is a table derived from two other (real or
+     derived) tables according to the rules of the particular join
+     type.  INNER, OUTER, NATURAL, and CROSS JOIN are supported.
+    
+
+    
+     Join Types
+
+     
+      CROSS JOIN
+
+      
+
+T1 CROSS JOIN T2
+
+
+       
+        For each combination of rows from
+        T1 and
+        T2 the derived table will contain a
+        row consisting of all columns in T1
+        followed by all columns in T2.  If
+        the tables have have N and M rows respectively, the joined
+        table will have N * M rows.  A cross join is essentially an
+        INNER JOIN ON TRUE.
+       
+
+       
+        
+         FROM T1 CROSS JOIN
+         T2 is equivalent to
+         FROM T1,
+         T2.
+        
+       
+      
+     
+
+     
+      Qualified JOINs
+      
+
+
+T1 { INNER | { LEFT | RIGHT | FULL } OUTER } JOIN T2 ON boolean expression
+T1 { INNER | { LEFT | RIGHT | FULL } OUTER } JOIN T2 USING ( join column list )
+
+        
+       
+        The words INNER and OUTER are
+        optional for all JOINs.  INNER is the default;
+        LEFTRIGHT, and
+        FULL are for OUTER JOINs only.
+       
+
+       
+        The join condition is specified in the
+        ON or USING clause.  (The meaning of the join condition
+        depends on the particular join type; see below.)  The ON
+        clause takes a boolean value expression of the same kind as is
+        used 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 the equality of
+        those columns as a set, resulting in a joined table having one
+        column for each common column listed and all of the other
+        columns from both tables.  Thus, USING (a, b,
+        c) is equivalent to ON (t1.a = t2.a AND
+        t1.b = t2.b AND t1.c = t2.c) with the exception that
+        if ON is used there will be two columns a, b, and c in the
+        result, whereas with USING there will be only one of each.
+       
+
+       
+        
+         INNER JOIN
+
+         
+          
+           For each row R1 of T1, the joined table has a row for each
+           row in T2 that satisfies the join condition with R1.
+          
+         
+        
+
+        
+         LEFT OUTER JOIN
+
+         
+          
+           First, an INNER JOIN is performed.  Then, for a row in T1
+           that does not satisfy the join condition with any row in
+           T2, a joined row is returned with NULL values in columns of
+           T2.  Thus, the joined table unconditionally has a row for each
+           row in T1.
+          
+         
+        
+         
+        
+         RIGHT OUTER JOIN
+
+         
+          
+           This is like a left join, only that the result table will
+           unconditionally have a row for each row in T2.
+          
+         
+        
+         
+        
+         FULL OUTER JOIN
+
+         
+          
+           First, an INNER JOIN is performed.  Then, for each row in
+           T1 that does not satisfy the join condition with any row in
+           T2, a joined row is returned with null values in columns of
+           T2.  Also, for each row of T2 that does not satisfy the
+           join condition with any row in T1, a joined row with null
+           values in the columns of T1 is returned.
+          
+         
+        
+       
+      
+     
+      
+     
+      NATURAL JOIN
+
+      
+
+T1 NATURAL { INNER | { LEFT | RIGHT | FULL } OUTER JOIN T2
+
+       
+        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.
+       
+      
+     
+    
+
+    
+     Joins of all types can be chained together or nested where either
+     or both of T1 and
+     T2 may be JOINed tables.  Parenthesis
+     can be used around JOIN clauses to control the join order which
+     are otherwise left to right.
+    
+   
+
+   
+    Subqueries
+
+    
+     Subqueries specifying a derived table must be enclosed in
+     parenthesis and must be named using an AS
+     clause.  (See .)
+    
+
+
+FROM (SELECT * FROM table1) AS alias_name
+
+
+    
+     This example is equivalent to FROM table1 AS
+     alias_name.  Many subquieries can be written as table
+     joins instead.
+    
+   
+
+   
+    Table and Column Aliases
+
+    
+     A temporary name can be given to tables and complex table
+     references to be used for references to the derived table in
+     further processing.  This is called a table
+     alias.
+
+FROM table_reference AS alias
+
+     Here, alias can be any regular
+     identifier.  The alias becomes the new name of the table
+     reference for the current query -- it is no longer possible to
+     refer to the table by the original name (if the table reference
+     was an ordinary base table).  Thus
+
+SELECT * FROM my_table AS m WHERE my_table.a > 5;
+
+     is not valid SQL syntax.  What will happen instead, as a
+     Postgres extension, is that an implict
+     table reference is added to the FROM clause, so the query is
+     processed as if it was written as
+
+SELECT * FROM my_table AS m, my_table WHERE my_table.a > 5;
+
+     Table aliases are mainly for notational convenience, but it is
+     necessary to use them when joining a table to itself, e.g.,
+
+SELECT * FROM my_table AS a CROSS JOIN my_table AS b ...
+
+     Additionally, an alias is required if the table reference is a
+     subquery.
+    
+
+    
+     Parenthesis are used to resolve ambiguities.  The following
+     statement will assign the alias b to the
+     result of the join, unlike the previous example:
+
+SELECT * FROM (my_table AS a CROSS JOIN my_table) AS b ...
+
+    
+
+    
+
+FROM table_reference alias
+
+     This form is equivalent the previously treated one; the
+     AS key word is noise.
+    
+
+    
+
+FROM table_reference AS alias ( column1 column2 , ... )
+
+     In addition to renaming the table as described above, the columns
+     of the table are also given temporary names.  If less column
+     aliases are specified than the actual table has columns, the last
+     columns are not renamed.  This syntax is especially useful for
+     self-joins or subqueries.
+    
+   
+
+   
+    Examples
+
+    
+
+FROM T1 INNER JOIN T2 USING (C)
+FROM T1 LEFT OUTER JOIN T2 USING (C)
+FROM (T1 RIGHT OUTER JOIN T2 ON (T1C1=T2C1)) AS DT1
+FROM (T1 FULL OUTER JOIN T2 USING (C)) AS DT1 (DT1C1, DT1C2)
+
+FROM T1 NATURAL INNER JOIN T2
+FROM T1 NATURAL LEFT OUTER JOIN T2
+FROM T1 NATURAL RIGHT OUTER JOIN T2
+FROM T1 NATURAL FULL OUTER JOIN T2
+
+FROM (SELECT * FROM T1) DT1 CROSS JOIN T2, T3
+FROM (SELECT * FROM T1) DT1, T2, T3
+
+
+     Above are some examples of joined tables and complex derived
+     tables.  Notice how the AS clause renames or names a derived
+     table and how the optional comma-separated list of column names
+     that follows gives names or renames the columns.  The last two
+     FROM clauses produce the same derived table from T1, T2, and T3.
+     The AS keyword was omitted in naming the subquery as DT1.  The
+     keywords OUTER and INNER are noise that can be omitted also.
+    
+   
+
+  
+
+  
+   WHERE clause
+
+   
+    The syntax of the WHERE clause is
+
+WHERE search condition
+
+    where search condition is any value
+    expression as defined in  that
+    returns a value of type boolean.
+   
+
+   
+    After the processing of the FROM clause is done, each row of the
+    derived table is checked against the search condition.  If the
+    result of the condition is true, the row is kept in the output
+    table, otherwise (that is, if the result is false or NULL) it is
+    discared.  The search condition typically references at least some
+    column in the table generated in the FROM clause; this is not
+    required, but otherwise the WHERE clause will be fairly useless.
+   
+
+   
+    
+     Before the implementation of the JOIN syntax, it was necessary to
+     put the join condition of an inner join in the WHERE clause.  For
+     example, these table expressions are equivalent:
+
+FROM a, b WHERE a.id = b.id AND b.val > 5
+
+     and
+
+FROM a INNER JOIN b ON (a.id = b.id) WHERE b.val > 5
+
+     or perhaps even
+
+FROM a NATURAL JOIN b WHERE b.val > 5
+
+     Which one of these you use is mainly a matter of style.  The JOIN
+     syntax in the FROM clause is probably not as portable to other
+     products.  For outer joins there is no choice in any case:  they
+     must be done in the FROM clause.
+    
+   
+
+
+FROM FDT WHERE
+    C1 > 5
+
+FROM FDT WHERE
+    C1 IN (1, 2, 3)
+FROM FDT WHERE
+    C1 IN (SELECT C1 FROM T2)
+FROM FDT WHERE
+    C1 IN (SELECT C3 FROM T2 WHERE C2 = FDT.C1 + 10)
+
+FROM FDT WHERE
+    C1 BETWEEN (SELECT C3 FROM T2 WHERE C2 = FDT.C1 + 10) AND 100
+
+FROM FDT WHERE
+    EXISTS (SELECT C1 FROM T2 WHERE C2 > FDT.C1)
+
+
+   
+    In the examples above, FDT is the table derived in the FROM
+    clause. Rows that do not meet the search condition of the where
+    clause are eliminated from FDT. Notice the use of scalar
+    subqueries as value expressions (C2 assumed UNIQUE).  Just like
+    any other query, the subqueries can employ complex table
+    expressions.  Notice how FDT is referenced in the subqueries.
+    Qualifying C1 as FDT.C1 is only necessary if C1 is the name of a
+    column in the derived input table of the subquery.  Qualifying the
+    column name adds clarity even when it is not needed.  The column
+    naming scope of an outer query extends into its inner queries.
+   
   
 
+
+
+
+
+  
+   GROUP BY and HAVING clauses     
+
+   
+    After passing the WHERE filter, the derived input table may be
+    subject to grouping, using the GROUP BY clause, and elimination of
+    group rows using the HAVING clause.  (The HAVING clause can also
+    be used without GROUP BY, but then it is equivalent to the WHERE
+    clause.)
+   
+
+   
+    In standard SQL, the GROUP BY clause takes a list of column names,
+    that specify a subrow, from the derived input table produced by
+    the previous WHERE or FROM clause and partitions the table into
+    groups with duplicate subrows such that within a column of the
+    subrow, no column value is distinct from other column values. The
+    resulting derived input table is a special type of table, called a
+    grouped table, which still contains all columns but only
+    references to columns of the grouped subrow, and group aggregates,
+    derived from any of the columns, may appear in derived column
+    value expressions in the query select list.  When deriving an
+    output table from a query using a grouped input table, each output
+    row is derived from a corresponding group/partition of the grouped
+    table. Aggregates computed in a derived output column are
+    aggregates on the current partition/group of the grouped input
+    table being processed.  Only one output table row results per
+    group/partition of the grouped input table.
+   
+
+   
+    Postgres has extended the GROUP BY clause to allow some
+    non-standard, but useful behavior. Derived output columns, given
+    names using an AS clause in the query select list, may appear in
+    the GROUP BY clause in combination with, or instead of, the input
+    table column names. Tables may also be grouped by arbitrary
+    expressions. If output table column names appear in the GROUP BY
+    list, then the input table is augmented with additional columns of
+    the output table columns listed in the GROUP BY clause. The value
+    for each row in the additional columns is computed from the value
+    expression that defines the output column in the query select
+    list. The augmented input table is grouped by the column names
+    listed in the GROUP BY clause. The resulting grouped augmented
+    input table is then treated according standard SQL GROUP BY
+    semantics. Only the columns of the unaugmented input table in the
+    grouped subrow (if any), and group aggregates, derived from any of
+    the columns of the unaugmented input table, may be referenced in
+    the value expressions of the derived output columns of the
+    query. Output columns derived with an aggregate expression cannot
+    be named in the GROUP BY clause.
+   
+
+   
+    A HAVING clause may optionally follow a GROUP BY clause.  The
+    HAVING clause selects or eliminates, depending on which
+    perspective is taken, groups from the grouped table derived in the
+    GROUP BY clause that precedes it.  The search condition is the
+    same type of expression allowed in a WHERE clause and may
+    reference any of the input table column names in the grouped
+    subrow, but may not reference any others or any named output
+    columns.  When the search condition results in TRUE the group is
+    retained, otherwise the group is eliminated.
+   
+  
+
+   
+    ORDER BY and LIMIT clauses
+      
+    
+     ORDER BY and LIMIT clauses are not clauses of a table expression.
+     They are optional clauses that may follow a query expression and
+     are discussed here because they are commonly used with the
+     clauses above.
+    
+
+    
+     ORDER BY takes a comma-separated list of columns and performs a
+     cascaded ordering of the table by the columns listed, in the
+     order listed.  The keyword DESC or ASC may follow any column name
+     or expression in the list to specify descending or ascending
+     ordering, respectively. Ascending order is the default.  The
+     ORDER BY clause conforms to the SQL standard but is extended in
+     Postgres.  Postgres allows ORDER BY to reference both output
+     table columns, as named in the select list using the AS clause,
+     and input table columns, as given by the table derived in the
+     FROM clause and other previous clauses. Postgres also extends
+     ORDER BY to allow ordering by arbitrary expressions. If used in a
+     query with a GROUP BY clause, the ORDER BY clause can only
+     reference output table column names and grouped input table
+     columns.
+    
+
+    
+     LIMIT is not a standard SQL clause.  LIMIT is a Postgres
+     extension that limits the number of rows that will be returned
+     from a query.  The rows returned by a query using the LIMIT
+     clause are random if no ORDER BY clause is specified.  A LIMIT
+     clause may optionally be followed by an OFFSET clause which
+     specifies a number of rows to be skipped in the output table
+     before returning the number of rows specified in the LIMIT
+     clause.
+    
+   
+]]>
   
+
+