Documentation Source Text

Check-in [c14dc7c23b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the extended-simple-select-stmt syntax diagram. Update the documentation on SELECT statements to better explain limitations on the use of ORDER BY and LIMIT in compound SELECTs.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c14dc7c23b533b2cde99a7baf981d5b29d676b1d
User & Date: drh 2014-01-30 14:11:01.082
Context
2014-01-30
15:03
Further enhancements to the SELECT documentation. (check-in: 979599b0b6 user: drh tags: trunk)
14:11
Add the extended-simple-select-stmt syntax diagram. Update the documentation on SELECT statements to better explain limitations on the use of ORDER BY and LIMIT in compound SELECTs. (check-in: c14dc7c23b user: drh tags: trunk)
11:15
Additional hyperlinks to "compound SELECT", "ORDER BY" and "LIMIT". (check-in: 1c8ccd6d21 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to art/syntax/bubble-generator-data.tcl.
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381







382
383
384
385
386
387


388
389
390
391
392
393
394
        {line VALUES {loop {line ( {loop expr ,} )} ,}}
     }
     compound-operator
  }
  simple-select-stmt {
     or
        {stack
            {opt {line WITH {opt RECURSIVE} {loop common-table-expression ,}}}
            {line SELECT {or nil DISTINCT ALL}
                                           {loop result-column ,}}
            {optx FROM {loop
                          table-or-subquery
                          {join-operator table-or-subquery join-constraint}}}
            {optx WHERE expr}
            {optx GROUP BY {loop expr ,} {optx HAVING expr}}
            {optx ORDER BY {loop ordering-term ,}}
            {optx LIMIT expr {optx {or OFFSET ,} expr}}
        }
        {line VALUES {loop {line ( {loop expr ,} )} ,}}
  }







  compound-select-stmt {
    stack
      {opt {line WITH {opt RECURSIVE} {loop common-table-expression ,}}}
      {line simple-select-stmt {loop
                    {line {or UNION {line UNION ALL} INTERSECT EXCEPT}
                          simple-select-stmt} nil}}


  }
  table-or-subquery {
     or
       {stack
          {line
             {optx /database-name .} /table-name
             {optx {optx AS} /table-alias}







<







<
<



>
>
>
>
>
>
>






>
>







362
363
364
365
366
367
368

369
370
371
372
373
374
375


376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
        {line VALUES {loop {line ( {loop expr ,} )} ,}}
     }
     compound-operator
  }
  simple-select-stmt {
     or
        {stack

            {line SELECT {or nil DISTINCT ALL}
                                           {loop result-column ,}}
            {optx FROM {loop
                          table-or-subquery
                          {join-operator table-or-subquery join-constraint}}}
            {optx WHERE expr}
            {optx GROUP BY {loop expr ,} {optx HAVING expr}}


        }
        {line VALUES {loop {line ( {loop expr ,} )} ,}}
  }
  extended-simple-select-stmt {
    stack
      {opt {line WITH {opt RECURSIVE} {loop common-table-expression ,}}}
      {line simple-select-stmt}
      {optx ORDER BY {loop ordering-term ,}}
      {optx LIMIT expr {optx {or OFFSET ,} expr}}
  }
  compound-select-stmt {
    stack
      {opt {line WITH {opt RECURSIVE} {loop common-table-expression ,}}}
      {line simple-select-stmt {loop
                    {line {or UNION {line UNION ALL} INTERSECT EXCEPT}
                          simple-select-stmt} nil}}
      {optx ORDER BY {loop ordering-term ,}}
      {optx LIMIT expr {optx {or OFFSET ,} expr}}
  }
  table-or-subquery {
     or
       {stack
          {line
             {optx /database-name .} /table-name
             {optx {optx AS} /table-alias}
Changes to art/syntax/compound-select-stmt.gif.

cannot compute difference between binary files

Added art/syntax/extended-simple-select-stmt.gif.

cannot compute difference between binary files

Changes to art/syntax/simple-select-stmt.gif.

cannot compute difference between binary files

Changes to art/syntax/syntax_linkage.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
set syntax_linkage(alter-table-stmt) {column-def sql-stmt}
set syntax_linkage(analyze-stmt) {{} sql-stmt}
set syntax_linkage(attach-stmt) {expr sql-stmt}
set syntax_linkage(begin-stmt) {{} sql-stmt}
set syntax_linkage(column-constraint) {{conflict-clause expr foreign-key-clause literal-value signed-number} column-def}
set syntax_linkage(column-def) {{column-constraint type-name} {alter-table-stmt create-table-stmt}}
set syntax_linkage(comment-syntax) {{} {}}
set syntax_linkage(commit-stmt) {{} sql-stmt}
set syntax_linkage(common-table-expression) {select-stmt {compound-select-stmt select-stmt simple-select-stmt}}
set syntax_linkage(compound-operator) {{} select-stmt}
set syntax_linkage(compound-select-stmt) {{common-table-expression simple-select-stmt} {}}
set syntax_linkage(conflict-clause) {{} {column-constraint table-constraint}}
set syntax_linkage(create-index-stmt) {{expr indexed-column} sql-stmt}
set syntax_linkage(create-table-stmt) {{column-def select-stmt table-constraint} sql-stmt}
set syntax_linkage(create-trigger-stmt) {{delete-stmt expr insert-stmt select-stmt update-stmt} sql-stmt}
set syntax_linkage(create-view-stmt) {select-stmt sql-stmt}
set syntax_linkage(create-virtual-table-stmt) {{} sql-stmt}
set syntax_linkage(cte-table-name) {{} {recursive-cte with-clause}}
set syntax_linkage(delete-stmt) {{expr qualified-table-name with-clause} {create-trigger-stmt sql-stmt}}
set syntax_linkage(delete-stmt-limited) {{expr ordering-term qualified-table-name with-clause} sql-stmt}
set syntax_linkage(detach-stmt) {{} sql-stmt}
set syntax_linkage(drop-index-stmt) {{} sql-stmt}
set syntax_linkage(drop-table-stmt) {{} sql-stmt}
set syntax_linkage(drop-trigger-stmt) {{} sql-stmt}
set syntax_linkage(drop-view-stmt) {{} sql-stmt}
set syntax_linkage(expr) {{literal-value raise-function select-stmt type-name} {attach-stmt column-constraint create-index-stmt create-trigger-stmt delete-stmt delete-stmt-limited insert-stmt join-constraint ordering-term result-column select-stmt simple-select-stmt table-constraint update-stmt update-stmt-limited}}

set syntax_linkage(foreign-key-clause) {{} {column-constraint table-constraint}}
set syntax_linkage(indexed-column) {{} {create-index-stmt table-constraint}}
set syntax_linkage(insert-stmt) {{expr select-stmt with-clause} {create-trigger-stmt sql-stmt}}
set syntax_linkage(join-constraint) {expr {select-stmt simple-select-stmt table-or-subquery}}
set syntax_linkage(join-operator) {{} {select-stmt simple-select-stmt}}
set syntax_linkage(literal-value) {{} {column-constraint expr}}
set syntax_linkage(numeric-literal) {{} {}}
set syntax_linkage(ordering-term) {expr {delete-stmt-limited select-stmt simple-select-stmt update-stmt-limited}}
set syntax_linkage(pragma-stmt) {pragma-value sql-stmt}
set syntax_linkage(pragma-value) {signed-number pragma-stmt}
set syntax_linkage(qualified-table-name) {{} {delete-stmt delete-stmt-limited update-stmt update-stmt-limited}}
set syntax_linkage(raise-function) {{} expr}
set syntax_linkage(recursive-cte) {cte-table-name {}}
set syntax_linkage(reindex-stmt) {{} sql-stmt}
set syntax_linkage(release-stmt) {{} sql-stmt}
set syntax_linkage(result-column) {expr {select-stmt simple-select-stmt}}
set syntax_linkage(rollback-stmt) {{} sql-stmt}
set syntax_linkage(savepoint-stmt) {{} sql-stmt}
set syntax_linkage(select-stmt) {{common-table-expression compound-operator expr join-constraint join-operator ordering-term result-column table-or-subquery} {common-table-expression create-table-stmt create-trigger-stmt create-view-stmt expr insert-stmt sql-stmt table-or-subquery with-clause}}
set syntax_linkage(signed-number) {{} {column-constraint pragma-value type-name}}
set syntax_linkage(simple-select-stmt) {{common-table-expression expr join-constraint join-operator ordering-term result-column table-or-subquery} compound-select-stmt}
set syntax_linkage(sql-stmt) {{alter-table-stmt analyze-stmt attach-stmt begin-stmt commit-stmt create-index-stmt create-table-stmt create-trigger-stmt create-view-stmt create-virtual-table-stmt delete-stmt delete-stmt-limited detach-stmt drop-index-stmt drop-table-stmt drop-trigger-stmt drop-view-stmt insert-stmt pragma-stmt reindex-stmt release-stmt rollback-stmt savepoint-stmt select-stmt update-stmt update-stmt-limited vacuum-stmt} sql-stmt-list}
set syntax_linkage(sql-stmt-list) {sql-stmt {}}
set syntax_linkage(table-constraint) {{conflict-clause expr foreign-key-clause indexed-column} create-table-stmt}
set syntax_linkage(table-or-subquery) {{join-constraint select-stmt} {select-stmt simple-select-stmt}}
set syntax_linkage(type-name) {signed-number {column-def expr}}
set syntax_linkage(update-stmt) {{expr qualified-table-name with-clause} {create-trigger-stmt sql-stmt}}
set syntax_linkage(update-stmt-limited) {{expr ordering-term qualified-table-name with-clause} sql-stmt}
set syntax_linkage(vacuum-stmt) {{} sql-stmt}
set syntax_linkage(with-clause) {{cte-table-name select-stmt} {delete-stmt delete-stmt-limited insert-stmt update-stmt update-stmt-limited}}
set syntax_order {sql-stmt-list sql-stmt alter-table-stmt analyze-stmt attach-stmt begin-stmt commit-stmt rollback-stmt savepoint-stmt release-stmt create-index-stmt indexed-column create-table-stmt column-def type-name column-constraint signed-number table-constraint foreign-key-clause conflict-clause create-trigger-stmt create-view-stmt create-virtual-table-stmt with-clause cte-table-name recursive-cte common-table-expression delete-stmt delete-stmt-limited detach-stmt drop-index-stmt drop-table-stmt drop-trigger-stmt drop-view-stmt expr raise-function literal-value numeric-literal insert-stmt pragma-stmt pragma-value reindex-stmt select-stmt simple-select-stmt compound-select-stmt table-or-subquery result-column join-operator join-constraint ordering-term compound-operator update-stmt update-stmt-limited qualified-table-name vacuum-stmt comment-syntax}








|

|














|
>







|












|









|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
set syntax_linkage(alter-table-stmt) {column-def sql-stmt}
set syntax_linkage(analyze-stmt) {{} sql-stmt}
set syntax_linkage(attach-stmt) {expr sql-stmt}
set syntax_linkage(begin-stmt) {{} sql-stmt}
set syntax_linkage(column-constraint) {{conflict-clause expr foreign-key-clause literal-value signed-number} column-def}
set syntax_linkage(column-def) {{column-constraint type-name} {alter-table-stmt create-table-stmt}}
set syntax_linkage(comment-syntax) {{} {}}
set syntax_linkage(commit-stmt) {{} sql-stmt}
set syntax_linkage(common-table-expression) {select-stmt {compound-select-stmt extended-simple-select-stmt select-stmt}}
set syntax_linkage(compound-operator) {{} select-stmt}
set syntax_linkage(compound-select-stmt) {{common-table-expression expr ordering-term simple-select-stmt} {}}
set syntax_linkage(conflict-clause) {{} {column-constraint table-constraint}}
set syntax_linkage(create-index-stmt) {{expr indexed-column} sql-stmt}
set syntax_linkage(create-table-stmt) {{column-def select-stmt table-constraint} sql-stmt}
set syntax_linkage(create-trigger-stmt) {{delete-stmt expr insert-stmt select-stmt update-stmt} sql-stmt}
set syntax_linkage(create-view-stmt) {select-stmt sql-stmt}
set syntax_linkage(create-virtual-table-stmt) {{} sql-stmt}
set syntax_linkage(cte-table-name) {{} {recursive-cte with-clause}}
set syntax_linkage(delete-stmt) {{expr qualified-table-name with-clause} {create-trigger-stmt sql-stmt}}
set syntax_linkage(delete-stmt-limited) {{expr ordering-term qualified-table-name with-clause} sql-stmt}
set syntax_linkage(detach-stmt) {{} sql-stmt}
set syntax_linkage(drop-index-stmt) {{} sql-stmt}
set syntax_linkage(drop-table-stmt) {{} sql-stmt}
set syntax_linkage(drop-trigger-stmt) {{} sql-stmt}
set syntax_linkage(drop-view-stmt) {{} sql-stmt}
set syntax_linkage(expr) {{literal-value raise-function select-stmt type-name} {attach-stmt column-constraint compound-select-stmt create-index-stmt create-trigger-stmt delete-stmt delete-stmt-limited extended-simple-select-stmt insert-stmt join-constraint ordering-term result-column select-stmt simple-select-stmt table-constraint update-stmt update-stmt-limited}}
set syntax_linkage(extended-simple-select-stmt) {{common-table-expression expr ordering-term simple-select-stmt} {}}
set syntax_linkage(foreign-key-clause) {{} {column-constraint table-constraint}}
set syntax_linkage(indexed-column) {{} {create-index-stmt table-constraint}}
set syntax_linkage(insert-stmt) {{expr select-stmt with-clause} {create-trigger-stmt sql-stmt}}
set syntax_linkage(join-constraint) {expr {select-stmt simple-select-stmt table-or-subquery}}
set syntax_linkage(join-operator) {{} {select-stmt simple-select-stmt}}
set syntax_linkage(literal-value) {{} {column-constraint expr}}
set syntax_linkage(numeric-literal) {{} {}}
set syntax_linkage(ordering-term) {expr {compound-select-stmt delete-stmt-limited extended-simple-select-stmt select-stmt update-stmt-limited}}
set syntax_linkage(pragma-stmt) {pragma-value sql-stmt}
set syntax_linkage(pragma-value) {signed-number pragma-stmt}
set syntax_linkage(qualified-table-name) {{} {delete-stmt delete-stmt-limited update-stmt update-stmt-limited}}
set syntax_linkage(raise-function) {{} expr}
set syntax_linkage(recursive-cte) {cte-table-name {}}
set syntax_linkage(reindex-stmt) {{} sql-stmt}
set syntax_linkage(release-stmt) {{} sql-stmt}
set syntax_linkage(result-column) {expr {select-stmt simple-select-stmt}}
set syntax_linkage(rollback-stmt) {{} sql-stmt}
set syntax_linkage(savepoint-stmt) {{} sql-stmt}
set syntax_linkage(select-stmt) {{common-table-expression compound-operator expr join-constraint join-operator ordering-term result-column table-or-subquery} {common-table-expression create-table-stmt create-trigger-stmt create-view-stmt expr insert-stmt sql-stmt table-or-subquery with-clause}}
set syntax_linkage(signed-number) {{} {column-constraint pragma-value type-name}}
set syntax_linkage(simple-select-stmt) {{expr join-constraint join-operator result-column table-or-subquery} {compound-select-stmt extended-simple-select-stmt}}
set syntax_linkage(sql-stmt) {{alter-table-stmt analyze-stmt attach-stmt begin-stmt commit-stmt create-index-stmt create-table-stmt create-trigger-stmt create-view-stmt create-virtual-table-stmt delete-stmt delete-stmt-limited detach-stmt drop-index-stmt drop-table-stmt drop-trigger-stmt drop-view-stmt insert-stmt pragma-stmt reindex-stmt release-stmt rollback-stmt savepoint-stmt select-stmt update-stmt update-stmt-limited vacuum-stmt} sql-stmt-list}
set syntax_linkage(sql-stmt-list) {sql-stmt {}}
set syntax_linkage(table-constraint) {{conflict-clause expr foreign-key-clause indexed-column} create-table-stmt}
set syntax_linkage(table-or-subquery) {{join-constraint select-stmt} {select-stmt simple-select-stmt}}
set syntax_linkage(type-name) {signed-number {column-def expr}}
set syntax_linkage(update-stmt) {{expr qualified-table-name with-clause} {create-trigger-stmt sql-stmt}}
set syntax_linkage(update-stmt-limited) {{expr ordering-term qualified-table-name with-clause} sql-stmt}
set syntax_linkage(vacuum-stmt) {{} sql-stmt}
set syntax_linkage(with-clause) {{cte-table-name select-stmt} {delete-stmt delete-stmt-limited insert-stmt update-stmt update-stmt-limited}}
set syntax_order {sql-stmt-list sql-stmt alter-table-stmt analyze-stmt attach-stmt begin-stmt commit-stmt rollback-stmt savepoint-stmt release-stmt create-index-stmt indexed-column create-table-stmt column-def type-name column-constraint signed-number table-constraint foreign-key-clause conflict-clause create-trigger-stmt create-view-stmt create-virtual-table-stmt with-clause cte-table-name recursive-cte common-table-expression delete-stmt delete-stmt-limited detach-stmt drop-index-stmt drop-table-stmt drop-trigger-stmt drop-view-stmt expr raise-function literal-value numeric-literal insert-stmt pragma-stmt pragma-value reindex-stmt select-stmt simple-select-stmt extended-simple-select-stmt compound-select-stmt table-or-subquery result-column join-operator join-constraint ordering-term compound-operator update-stmt update-stmt-limited qualified-table-name vacuum-stmt comment-syntax}
Changes to pages/lang.in.
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
<p>^The REPLACE command is an alias for the "[ON CONFLICT | INSERT OR REPLACE]"
variant of the [INSERT] command.  
This alias is provided for compatibility other SQL database engines.  See the 
[INSERT] command documentation for additional information.</p>  

<tcl>
###############################################################################
Section {WITH clause} with {{common table expressions}}

RecursiveBubbleDiagram with-clause
</tcl>

<p>Common Table Expressions or CTEs act like temporary [views] that exist
only for the duration of a single SQL statement.  There are two kinds of
common table expressions: "ordinary" and "recursive". Ordinary 







|







3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
<p>^The REPLACE command is an alias for the "[ON CONFLICT | INSERT OR REPLACE]"
variant of the [INSERT] command.  
This alias is provided for compatibility other SQL database engines.  See the 
[INSERT] command documentation for additional information.</p>  

<tcl>
###############################################################################
Section {WITH clause} with {{common table expressions} WITH}

RecursiveBubbleDiagram with-clause
</tcl>

<p>Common Table Expressions or CTEs act like temporary [views] that exist
only for the duration of a single SQL statement.  There are two kinds of
common table expressions: "ordinary" and "recursive". Ordinary 
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081

<p>A recursive common table expression can be used to write a query that
walks a tree or graph.  A recursive common table expression has the same
basic syntax as an ordinary common table expression, but with the following
additional features:

<ol>
<li> The "select-stmt"
     must be a [compound select] where the right-most [compound-operator] is
     either UNION or UNION ALL.
<li> The table named on the left-hand side of the AS keyword must appear
     exactly once in the FROM clause of the right-most SELECT statement
     of the compound select, and nowhere else.
</ol>








|







3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081

<p>A recursive common table expression can be used to write a query that
walks a tree or graph.  A recursive common table expression has the same
basic syntax as an ordinary common table expression, but with the following
additional features:

<ol>
<li> The "[select-stmt]"
     must be a [compound select] where the right-most [compound-operator] is
     either UNION or UNION ALL.
<li> The table named on the left-hand side of the AS keyword must appear
     exactly once in the FROM clause of the right-most SELECT statement
     of the compound select, and nowhere else.
</ol>

3618
3619
3620
3621
3622
3623
3624












3625
















3626
3627
3628
3629
3630
3631
3632
<p>The SELECT statement is the most complicated command in the SQL language.
To make the description easier to follow, some of the passages below describe
the way the data returned by a SELECT statement is determined as a series of
steps. It is important to keep in mind that this is purely illustrative -
in practice neither SQLite nor any other SQL engine is required to follow 
this or any other specific process.













<h3>Simple Select Processing</h3>

















<p>Generating the results of a simple SELECT
statement is presented as a four step process in the description below:

<ol>
  <li> <p>[FROM clause] processing: The input data for the simple SELECT is
       determined. The input data is either implicitly a single row with 0







>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
<p>The SELECT statement is the most complicated command in the SQL language.
To make the description easier to follow, some of the passages below describe
the way the data returned by a SELECT statement is determined as a series of
steps. It is important to keep in mind that this is purely illustrative -
in practice neither SQLite nor any other SQL engine is required to follow 
this or any other specific process.

<p>The "[select-stmt]" syntax diagram above attempts to show as much of the
SELECT statement syntax as possible in a single diagram, as some readers
find this helpful.  Alternative syntax diagrams that break the syntax down
into smaller chunks are shown elsewhere in this document.

<p>Note that there are paths through the "select-stmt" syntax diagram that
are not allowed in practice.  For example, an [ORDER BY] or [LIMIT] clause
can only occur on the right-most SELECT of a [compound select], even though
the diagram shows that they can occur anywhere.  Restrictions such as this
are described in the subsequent text.

<tcl>hd_fragment simpleselect {simple SELECT}</tcl>
<h3>Simple Select Processing</h3>

<p>The core of a SELECT statement is a "simple SELECT" shown by the
[simple-select-stmt] syntax diagram below.  
In practice, most SELECT statements are simple SELECT statements, 
though with the possible addition of an [ORDER BY] clause,
a [LIMIT] clause, and sometimes a [WITH] clause, as shown in 
the [extended-simple-select-stmt] syntax diagram.  The [ORDER BY],
[LIMIT], and [WITH] clauses are omitted from the simple-select-stmt
syntax diagram because simple-select-stmt is used in the definition of
a [compound SELECT] and those extra clauses are not allowed in that
context.

<tcl>
HiddenBubbleDiagram extended-simple-select-stmt
RecursiveBubbleDiagram simple-select-stmt
</tcl>

<p>Generating the results of a simple SELECT
statement is presented as a four step process in the description below:

<ol>
  <li> <p>[FROM clause] processing: The input data for the simple SELECT is
       determined. The input data is either implicitly a single row with 0
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868

3869
3870
3871






3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
DISTINCT are present, then the behavior is as if ALL were specified. 
^If the simple SELECT is a SELECT DISTINCT, then duplicate rows are removed
from the set of result rows before it is returned. ^For the purposes of
detecting duplicate rows, two NULL values are considered to be equal. ^The
normal rules for selecting a collation sequence to compare text values with
apply.

<h3>Compound Select Statements
<tcl>hd_fragment compound</tcl>
<tcl>hd_keywords {compound select} {compound query} {compound SELECT} {compound SELECTs}</tcl>
</h3>


<p>Two or more simple SELECT statements may be connected together to form
a compound SELECT using the UNION, UNION ALL, INTERSECT or EXCEPT operator.






^In a compound SELECT, all the constituent SELECTs must return the same 
number of result columns. ^As the components of a compound SELECT must
be simple SELECT statements, they may not contain [ORDER BY] or [LIMIT] clauses.
^[ORDER BY] and [LIMIT] clauses may only occur at the end of the entire compound
SELECT.  

<p>^A compound SELECT created using UNION ALL operator returns all the rows
from the SELECT to the left of the UNION ALL operator, and all the rows
from the SELECT to the right of it. ^The UNION operator works the same way as
UNION ALL, except that duplicate rows are removed from the final result set.
^The INTERSECT operator returns the intersection of the results of the left and
right SELECTs.  ^The EXCEPT operator returns the subset of rows returned by the







<
|
|
|
>

|
|
>
>
>
>
>
>
|



|







3886
3887
3888
3889
3890
3891
3892

3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
DISTINCT are present, then the behavior is as if ALL were specified. 
^If the simple SELECT is a SELECT DISTINCT, then duplicate rows are removed
from the set of result rows before it is returned. ^For the purposes of
detecting duplicate rows, two NULL values are considered to be equal. ^The
normal rules for selecting a collation sequence to compare text values with
apply.


<tcl>
hd_fragment compound {compound select} {compound query} {compound SELECT} {compound SELECTs}
</tcl>
<h3>Compound Select Statements</h3>

<p>Two or more [simple SELECT] statements may be connected together to form
a compound SELECT using the UNION, UNION ALL, INTERSECT or EXCEPT operator,
as shown by the following diagram:

<tcl>
RecursiveBubbleDiagram compound-select-stmt
</tcl>

<p>^In a compound SELECT, all the constituent SELECTs must return the same 
number of result columns. ^As the components of a compound SELECT must
be simple SELECT statements, they may not contain [ORDER BY] or [LIMIT] clauses.
^[ORDER BY] and [LIMIT] clauses may only occur at the end of the entire compound
SELECT, and then only if the final element of the compound is not a [VALUES] clause.

<p>^A compound SELECT created using UNION ALL operator returns all the rows
from the SELECT to the left of the UNION ALL operator, and all the rows
from the SELECT to the right of it. ^The UNION operator works the same way as
UNION ALL, except that duplicate rows are removed from the final result set.
^The INTERSECT operator returns the intersection of the results of the left and
right SELECTs.  ^The EXCEPT operator returns the subset of rows returned by the
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911


3912
3913
3914

3915
3916
3917
3918
3919
3920
3921
<p>^(When three or more simple SELECTs are connected into a compound SELECT,
they group from left to right. In other words, if "A", "B" and "C" are all
simple SELECT statements, (A op B op C) is processed as ((A op B) op C).)^

</p>

<tcl>hd_fragment orderby {order by} {ORDER BY}</tcl>
<h3>ORDER BY clauses</h3>

<p>If a SELECT statement that returns more than one row does not have an
ORDER BY clause, the order in which the rows are returned is undefined.
Or, if a SELECT statement does have an ORDER BY clause, then the list of
expressions attached to the ORDER BY determine the order in which rows
are returned to the user.


In a [compound SELECT] statement, only the last (right-most) SELECT may have
an ORDER BY clause and that ORDER BY clause will apply across all elements of
the compound.



<p>^Rows are first sorted based on the results of
evaluating the left-most expression in the ORDER BY list, then ties are broken
by evaluating the second left-most expression and so on. The order in which
two rows for which all ORDER BY expressions evaluate to equal values are
returned is undefined. ^Each ORDER BY expression may be optionally followed







|






>
>
|
|
|
>







3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
<p>^(When three or more simple SELECTs are connected into a compound SELECT,
they group from left to right. In other words, if "A", "B" and "C" are all
simple SELECT statements, (A op B op C) is processed as ((A op B) op C).)^

</p>

<tcl>hd_fragment orderby {order by} {ORDER BY}</tcl>
<h3>The ORDER BY clause</h3>

<p>If a SELECT statement that returns more than one row does not have an
ORDER BY clause, the order in which the rows are returned is undefined.
Or, if a SELECT statement does have an ORDER BY clause, then the list of
expressions attached to the ORDER BY determine the order in which rows
are returned to the user.

<p>
In a [compound SELECT] statement, only the last or right-most [simple SELECT]
may have an ORDER BY clause. That ORDER BY clause will apply across all elements of
the compound. If the right-most element of a [compound SELECT] is a [VALUES] clause,
then no ORDER BY clause is allowed on that statement.


<p>^Rows are first sorted based on the results of
evaluating the left-most expression in the ORDER BY list, then ties are broken
by evaluating the second left-most expression and so on. The order in which
two rows for which all ORDER BY expressions evaluate to equal values are
returned is undefined. ^Each ORDER BY expression may be optionally followed
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979



3980
3981


3982
3983
3984
3985
3986
3987
3988
the expression is handled as an alias for the result column that it has been
matched against. Otherwise, the next SELECT to the right is tried, and so on.)^
^If no matching expression can be found in the result columns of any
constituent SELECT, it is an error. ^Each term of the ORDER BY clause is
processed separately and may be matched against result columns from different
SELECT statements in the compound.</p>

<tcl>hd_fragment limitoffset {LIMIT}</tcl>
<h3>LIMIT and OFFSET clauses</h3>

<p>The LIMIT clause is used to place an upper bound on the number of rows
returned by the entire SELECT statement.  In a [compound SELECT], only the



last (right-most) SELECT may contain a LIMIT clause.  In a [compound SELECT], 
the LIMIT clause applies to the entire compound, not just the final SELECT.



<p>^Any scalar expression may be used in the 
LIMIT clause, so long as it evaluates to an integer or a value that can be
losslessly converted to an integer. ^If the expression evaluates to a NULL 
value or any other value that cannot be losslessly converted to an integer, an
error is returned. ^If the LIMIT expression evaluates to a negative value,
then there is no upper bound on the number of rows returned. ^Otherwise, the







|
|


|
>
>
>
|

>
>







4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
the expression is handled as an alias for the result column that it has been
matched against. Otherwise, the next SELECT to the right is tried, and so on.)^
^If no matching expression can be found in the result columns of any
constituent SELECT, it is an error. ^Each term of the ORDER BY clause is
processed separately and may be matched against result columns from different
SELECT statements in the compound.</p>

<tcl>hd_fragment limitoffset {LIMIT} {OFFSET}</tcl>
<h3>The LIMIT clause</h3>

<p>The LIMIT clause is used to place an upper bound on the number of rows
returned by the entire SELECT statement.

<p>In a [compound SELECT], only the
last (right-most) [simple SELECT] may contain a LIMIT clause.  
In a [compound SELECT], 
the LIMIT clause applies to the entire compound, not just the final SELECT.
If the right-most [simple SELECT] is a [VALUES clause] then no LIMIT clause
is allowed.

<p>^Any scalar expression may be used in the 
LIMIT clause, so long as it evaluates to an integer or a value that can be
losslessly converted to an integer. ^If the expression evaluates to a NULL 
value or any other value that cannot be losslessly converted to an integer, an
error is returned. ^If the LIMIT expression evaluates to a negative value,
then there is no upper bound on the number of rows returned. ^Otherwise, the
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
<p>^Instead of a separate OFFSET clause, the LIMIT clause may specify two
scalar expressions separated by a comma. ^In this case, the first expression
is used as the OFFSET expression and the second as the LIMIT expression.
This is counter-intuitive, as when using the OFFSET clause the second of
the two expressions is the OFFSET and the first the LIMIT. This is intentional
- it maximizes compatibility with other SQL database systems.

<tcl>hd_fragment values {VALUES clause}</tcl>
<h3>VALUES clauses</h3>

<p>The phrase "VALUES(<i>expr-list</i>)" means the same thing
as "SELECT <i>expr-list</i>".  The phrase
"VALUES(<i>expr-list-1</i>),...,(<i>expr-list-N</i>)" means the same
thing as "SELECT <i>expr-list-1</i> UNION ALL ... UNION ALL
SELECT <i>expr-list-N</i>".  There is no advantage to using one form
over the other.  Both forms yield the same result and both forms use







|
|







4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
<p>^Instead of a separate OFFSET clause, the LIMIT clause may specify two
scalar expressions separated by a comma. ^In this case, the first expression
is used as the OFFSET expression and the second as the LIMIT expression.
This is counter-intuitive, as when using the OFFSET clause the second of
the two expressions is the OFFSET and the first the LIMIT. This is intentional
- it maximizes compatibility with other SQL database systems.

<tcl>hd_fragment values {VALUES clause} VALUES</tcl>
<h3>The VALUES clause</h3>

<p>The phrase "VALUES(<i>expr-list</i>)" means the same thing
as "SELECT <i>expr-list</i>".  The phrase
"VALUES(<i>expr-list-1</i>),...,(<i>expr-list-N</i>)" means the same
thing as "SELECT <i>expr-list-1</i> UNION ALL ... UNION ALL
SELECT <i>expr-list-N</i>".  There is no advantage to using one form
over the other.  Both forms yield the same result and both forms use