Table Expressions

Table expressions define a data source in the FROM sub-clause ofsimple SELECT clauses, or as parameter toTABLE.

SQL Joins are a particular kind of tableexpression.

Synopsis

table_name@index_namefunc_application[preparable_stmt](select_stmtjoined_table)WITHORDINALITYAStable_alias_name(name,)joined_table

Parameters

ParameterDescription
table_nameA table or view name.
table_alias_nameA name to use in an aliased table expression.
nameOne or more aliases for the column names, to use in an aliased table expression.
index_nameOptional syntax to force index selection.
func_applicationResults from a function.
preparable_stmtUse the result rows of a preparable statement.
select_stmtA selection query to use as subquery.
joined_tableA join expression.

Table expressions language

The synopsis above really defines a mini-language to constructcomplex table expressions from simpler parts.

ConstructDescriptionExamples
table_name [@ scan_parameters]Access a table or view.accounts, accounts@name_idx
function_name ( exprs … )Generate tabular data using a scalar function or table generator function.sin(1.2), generate_series(1,10)
<table expr> [AS] name [( name [, …] )]Rename a table and optionally columns.accounts a, accounts AS a, accounts AS a(id, b)
<table expr> WITH ORDINALITYEnumerate the result rows.accounts WITH ORDINALITY
<table expr> JOIN <table expr> ON …Join expression.orders o JOIN customers c ON o.customer_id = c.id
(… subquery …)A selection query used as subquery.(SELECT * FROM customers c)
[… statement …]Use the result rows of an explainable statement.This is a CockroachDB extension.[SHOW COLUMNS FROM accounts]

The following sections provide details on each of these options.

Table expressions that generate data

The following sections describe primary table expressions that producedata.

Access a table or view

Table or view names

Syntax:

  1. identifier
  2. identifier.identifier
  3. identifier.identifier.identifier

A single SQL identifier in a table expression context designatesthe contents of the table, view, or sequence with that namein the current database, as configured by SET DATABASE.

If the name is composed of two or more identifiers, name resolution rules apply.

For example:

  1. > SELECT * FROM users; -- uses table `users` in the current database
  1. > SELECT * FROM mydb.users; -- uses table `users` in database `mydb`

Force index selection

By using the explicit index annotation, you can override CockroachDB's index selection and use a specific index when reading from a named table.

Note:

Index selection can impact performance, but does not change the result of a query.

The syntax to force a scan of a specific index is:

  1. > SELECT * FROM table@my_idx;

This is equivalent to the longer expression:

  1. > SELECT * FROM table@{FORCE_INDEX=my_idx};

New in v19.1: The syntax to force a reverse scan of a specific index is:

  1. > SELECT * FROM table@{FORCE_INDEX=my_idx,DESC};

Forcing a reverse can is sometimes useful during performance tuning. For reference, the full syntax for choosing an index and its scan direction is

  1. SELECT * FROM table@{FORCE_INDEX=idx[,DIRECTION]}

where the optional DIRECTION is either ASC (ascending) or DESC (descending).

When a direction is specified, that scan direction is forced; otherwise the cost-based optimizer is free to choose the direction it calculates will result in the best performance.

You can verify that the optimizer is choosing your desired scan direction using EXPLAIN (OPT). For example, given the table

  1. > CREATE TABLE kv (K INT PRIMARY KEY, v INT);

you can check the scan direction with:

  1. > EXPLAIN (opt) SELECT * FROM kv@{FORCE_INDEX=primary,DESC};

  1. text

scan kv,rev
└── flags: force-index=primary,rev
(2 rows)

To see all indexes available on a table, use SHOW INDEXES.

Access a common table expression

A single identifier in a table expression context can refer to acommon table expression definedearlier.

For example:

  1. > WITH a AS (SELECT * FROM users)
  2. SELECT * FROM a; -- "a" refers to "WITH a AS .."

Results from a function

A table expression can use the results from a function application asa data source.

Syntax:

  1. name ( arguments... )

The name of a function, followed by an opening parenthesis, followedby zero or more scalar expressions, followed bya closing parenthesis.

The resolution of the function name follows the same rules as theresolution of table names. See NameResolution for more details.

Scalar function as data source

When a function returning a singlevalue isused as a table expression, it is interpreted as tabular data with asingle column and single row containing the function results.

For example:

  1. > SELECT * FROM sin(3.2)
  1. +-----------------------+
  2. | sin |
  3. +-----------------------+
  4. | -0.058374143427580086 |
  5. +-----------------------+

Note:
CockroachDB only supports this syntax for compatibility with PostgreSQL. The canonical syntax to evaluate scalar functions is as a direct target of SELECT, for example SELECT sin(3.2).

Table generator functions

Some functions directly generate tabular data with multiple rows froma single function application. This is also called a "set-returningfunction".

For example:

  1. > SELECT * FROM generate_series(1, 3);
  1. +-----------------+
  2. | generate_series |
  3. +-----------------+
  4. | 1 |
  5. | 2 |
  6. | 3 |
  7. +-----------------+

Set-returning functions (SRFs) can now be accessed using (SRF).x where x is one of the following:

  • The name of a column returned from the function
  • * to denote all columns.
    For example (note that the output of queries against information_schema will vary per database):
  1. > SELECT (i.keys).* FROM (SELECT information_schema._pg_expandarray(indkey) AS keys FROM pg_index) AS i;
  1. x | n
  2. ---+---
  3. 1 | 1
  4. 2 | 1
  5. (2 rows)

Note:

Currently CockroachDB only supports a small set of generator functions compatible with the PostgreSQL set-generating functions with the samenames.

Operators that extend a table expression

The following sections describe table expressions that change themetadata around tabular data, or add more data, without modifying thedata of the underlying operand.

Aliased table expressions

Aliased table expressions rename tables and columns temporarily inthe context of the current query.

Syntax:

  1. <table expr> AS <name>
  2. <table expr> AS <name>(<colname>, <colname>, ...)

In the first form, the table expression is equivalent to its left operandwith a new name for the entire table, and where columns retain their original name.

In the second form, the columns are also renamed.

For example:

  1. > SELECT c.x FROM (SELECT COUNT(*) AS x FROM users) AS c;
  1. > SELECT c.x FROM (SELECT COUNT(*) FROM users) AS c(x);

Ordinality annotation

Syntax:

  1. <table expr> WITH ORDINALITY

Designates a data source equivalent to the table expression operand withan extra "Ordinality" column that enumerates every row in the data source.

For example:

  1. > SELECT * FROM (VALUES('a'),('b'),('c'));
  1. +---------+
  2. | column1 |
  3. +---------+
  4. | a |
  5. | b |
  6. | c |
  7. +---------+
  1. > SELECT * FROM (VALUES ('a'), ('b'), ('c')) WITH ORDINALITY;
  1. +---------+------------+
  2. | column1 | ordinality |
  3. +---------+------------+
  4. | a | 1 |
  5. | b | 2 |
  6. | c | 3 |
  7. +---------+------------+

Note:

WITH ORDINALITY necessarily prevents some optimizations of the surrounding query. Use it sparingly if performance is a concern, and always check the output of EXPLAIN in case of doubt.

Join expressions

Join expressions combine the results of two or more table expressionsbased on conditions on the values of particular columns.

See Join Expressions for more details.

Using other queries as table expressions

The following sections describe how to use the results produced byanother SQL query or statement as a table expression.

Subqueries as table expressions

Any selectionquery enclosedbetween parentheses can be used as a table expression, includingsimple SELECT clauses. This is called a"subquery".

Syntax:

  1. ( ... subquery ... )

For example:

  1. > SELECT c+2 FROM (SELECT COUNT(*) AS c FROM users);
  1. > SELECT * FROM (VALUES(1), (2), (3));
  1. > SELECT firstname || ' ' || lastname FROM (TABLE employees);

Note:

  • See also Subqueries for more details and performance best practices.
  • To use other statements that produce data in a table expression, for example SHOW, use the square bracket notation.

Using the output of other statements

Syntax:

  1. [ <statement> ]

An explainable statementbetween square brackets in a table expression context designates theoutput of executing said statement.

Note:

This is a CockroachDB extension. This syntax complements the subquery syntax using parentheses, which is restricted to selection queries. It was introduced to enable use of any explainable statement as subquery, including SHOW and other non-query statements.

For example:

  1. > SELECT "column_name" FROM [SHOW COLUMNS FROM customer];
  1. +-------------+
  2. | column_name |
  3. +-------------+
  4. | id |
  5. | name |
  6. | address |
  7. +-------------+
  8. (3 rows)

The following statement inserts Albert in the employee table andimmediately creates a matching entry in the management table with theauto-generated employee ID, without requiring a round trip with the SQLclient:

  1. > INSERT INTO management(manager, reportee)
  2. VALUES ((SELECT id FROM employee WHERE name = 'Diana'),
  3. (SELECT id FROM [INSERT INTO employee(name) VALUES ('Albert') RETURNING id]));

Composability

Table expressions are used in the SELECT andTABLE variants of selectionclauses, and thus can appear everywhere wherea selection clause is possible. For example:

  1. > SELECT ... FROM <table expr>, <table expr>, ...
  2. > TABLE <table expr>
  3. > INSERT INTO ... SELECT ... FROM <table expr>, <table expr>, ...
  4. > INSERT INTO ... TABLE <table expr>
  5. > CREATE TABLE ... AS SELECT ... FROM <table expr>, <table expr>, ...
  6. > UPSERT INTO ... SELECT ... FROM <table expr>, <table expr>, ...

For more options to compose query results, see Selection Queries.

See also

Was this page helpful?
YesNo