This section concentrates on single-source selects. are discussed in a following section.

    Syntax

    When selecting from a single table or view, the FROM clause need not contain anything more than the name. An alias may be useful or even necessary if there are subqueries that refer to the main select statement (as they often do — subqueries like this are called correlated subqueries).

    Examples

    1. select id, name, sex, age from actors
    2. where state = 'Ohio'
    1. select * from birds
    2. where type = 'flightless'
    3. order by family, genus, species
    1. select firstname,
    2. middlename,
    3. lastname,
    4. date_of_birth,
    5. (select name from schools s where p.school = s.id) schoolname
    6. from pupils p
    7. where year_started = '2012'
    8. order by schoolname, date_of_birth

    A selectable stored procedure is a procedure that:

    • contains at least one output parameter, and

    • utilizes the SUSPEND keyword so the caller can fetch the output rows one by one, just as when selecting from a table or view.

    The output parameters of a selectable stored procedure correspond to the columns of a regular table.

    Selecting from a stored procedure without input parameters is just like selecting from a table or view:

    Any required input parameters must be specified after the procedure name, enclosed in parentheses:

    1. where alt >= 20
    2. order by az, alt

    Values for optional parameters (that is, parameters for which default values have been defined) may be omitted or provided. However, if you provide them only partly, the parameters you omit must all be at the tail end.

    Supposing that the procedure from the previous example has two optional parameters: min_magn (numeric(3,1)) and spectral_class (varchar(12)), the following queries are all valid:

    1. select name, az, alt
    2. from visible_stars('Brugge', current_date, '22:30');
    3. select name, az, alt
    4. from visible_stars('Brugge', current_date, '22:30', 4.0);
    5. select name, az, alt
    6. from visible_stars('Brugge', current_date, '22:30', 4.0, 'G');

    But this one isn’t, because there’s a “hole” in the parameter list:

    1. select name, az, alt
    2. from visible_stars('Brugge', current_date, '22:30', 'G');

    An alias for a selectable stored procedure is specified after the parameter list:

    1. select
    2. number,
    3. (select name from contestants c where c.number = gw.number)
    4. from get_winners('#34517', 'AMS') gw

    If you refer to an output parameter (“column”) by qualifying it with the full procedure name, the procedure alias should be omitted:

    1. select
    2. number,
    3. (select name from contestants c where c.number = get_winners.number)
    4. from get_winners('#34517', 'AMS')

    See also

    , CREATE PROCEDURE

    A derived table is a valid SELECT statement enclosed in parentheses, optionally followed by a table alias and/or column aliases. The result set of the statement acts as a virtual table which the enclosing statement can query.

    Syntax

    The set returned data set by this “SELECT FROM (SELECT FROM..)” style of statement is a virtual table that can be queried within the enclosing statement, as if it were a regular table or view.

    Sample using a derived table

    The derived table in the query below returns the list of table names in the database and the number of columns in each. A “drill-down” query on the derived table returns the counts of fields and the counts of tables having each field count:

    1. SELECT
    2. FIELDCOUNT,
    3. COUNT(RELATION) AS NUM_TABLES
    4. FROM (SELECT
    5. R.RDB$RELATION_NAME RELATION,
    6. COUNT(*) AS FIELDCOUNT
    7. FROM RDB$RELATIONS R
    8. JOIN RDB$RELATION_FIELDS RF
    9. ON RF.RDB$RELATION_NAME = R.RDB$RELATION_NAME
    10. GROUP BY RELATION)
    11. GROUP BY FIELDCOUNT
    1. SELECT
    2. DBINFO.DESCR, DBINFO.DEF_CHARSET
    3. FROM (SELECT *
    4. FROM RDB$DATABASE) DBINFO

    A more useful example

    Suppose we have a table COEFFS which contains the coefficients of a number of quadratic equations we have to solve. It has been defined like this:

    1. create table coeffs (
    2. a double precision not null,
    3. b double precision not null,
    4. c double precision not null,
    5. constraint chk_a_not_zero check (a <> 0)
    6. )

    Depending on the values of a, b and c, each equation may have zero, one or two solutions. It is possible to find these solutions with a single-level query on table COEFFS, but the code will look rather messy and several values (like the discriminant) will have to be calculated multiple times per row. A derived table can help keep things clean here:

    1. select
    2. iif (D >= 0, (-b - sqrt(D)) / denom, null) sol_1,
    3. iif (D > 0, (-b + sqrt(D)) / denom, null) sol_2
    4. from
    5. (select b, b*b - 4*a*c, 2*a from coeffs) (b, D, denom)

    If we want to show the coefficients next to the solutions (which may not be a bad idea), we can alter the query like this:

    1. select
    2. a, b, c,
    3. iif (D >= 0, (-b - sqrt(D)) / denom, null) sol_1,
    4. iif (D > 0, (-b + sqrt(D)) / denom, null) sol_2
    5. from
    6. (select a, b, c, b*b - 4*a*c as D, 2*a as denom
    7. from coeffs)

    Notice that whereas the first query used a column aliases list for the derived table, the second adds aliases internally where needed. Both methods work, as long as every column is guaranteed to have a name.

    A common table expression or CTE is a more complex variant of the derived table, but it is also more powerful. A preamble, starting with the keyword WITH, defines one or more named CTE‘s, each with an optional column aliases list. The main query, which follows the preamble, can then access these CTE‘s as if they were regular tables or views. The CTE‘s go out of scope once the main query has run to completion.

    For a full discussion of CTE‘s, please refer to the section .

    The following is a rewrite of our derived table example as a CTE:

    Except for the fact that the calculations that have to be made first are now at the beginning, this isn’t a great improvement over the derived table version. But we can now also eliminate the double calculation of sqrt(D) for every row:

    1. with vars (b, D, denom) as (
    2. select b, b*b - 4*a*c, 2*a from coeffs
    3. ),
    4. vars2 (b, D, denom, sqrtD) as (
    5. select b, D, denom, iif (D >= 0, sqrt(D), null) from vars
    6. )
    7. select
    8. iif (D >= 0, (-b - sqrtD) / denom, null) sol_1,
    9. from vars2

    The code is a little more complicated now, but it might execute more efficiently (depending on what takes more time: executing the SQRT function or passing the values of b, D and denom through an extra CTE). Incidentally, we could have done the same with derived tables, but that would involve nesting.

    See also