> ## Documentation Index
> Fetch the complete documentation index at: https://cockroachlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Selection Queries

export const InternalLink = ({version, path = "", children, ...props}) => {
  let detectedVersion = version || "stable";
  if (typeof window !== 'undefined' && !version) {
    const match = window.location.pathname.match(/\/docs\/([^/]+)/);
    if (match) {
      detectedVersion = match[1];
    }
  }
  const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
  return <a href={`/docs/${detectedVersion}/${normalizedPath}`} {...props}>
      {children}
    </a>;
};

Selection queries read and process data in CockroachDB.  They are more general than <InternalLink path="select-clause">simple `SELECT` clauses</InternalLink>: they can group one or more [selection clauses](#selection-clauses) with [set operations](#set-operations) and can request a <InternalLink path="order-by">specific ordering</InternalLink> or <InternalLink path="limit-offset">row limit</InternalLink>.

Selection queries can occur:

* At the top level of a query, like other <InternalLink path="sql-statements">SQL statements</InternalLink>.
* Between parentheses as a <InternalLink path="table-expressions#use-a-subquery">subquery</InternalLink>.
* As [operand to other statements](#use-selection-queries-with-other-statements) that take tabular data as input, for example <InternalLink path="insert">`INSERT`</InternalLink>, <InternalLink path="upsert">`UPSERT`</InternalLink>,  <InternalLink path="create-table-as">`CREATE TABLE AS`</InternalLink>, or <InternalLink path="alter-table#split-at">`ALTER ... SPLIT AT`</InternalLink>.

## Synopsis

<img src="https://mintcdn.com/cockroachlabs/hRoSoqt0mqHbZVjm/images/sql-diagrams/v23.1/select.svg?fit=max&auto=format&n=hRoSoqt0mqHbZVjm&q=85&s=58d5752744e156819928356ed44bfc4c" alt="select syntax diagram" style={{maxWidth: "100%", overflowX: "auto"}} width="1349" height="505" data-path="images/sql-diagrams/v23.1/select.svg" />

## Parameters

| Parameter            | Description                                                                                                                                                                                                                          |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `common_table_expr`  | See <InternalLink path="common-table-expressions">Common Table Expressions</InternalLink>.                                                                                                                                           |
| `select_clause`      | A valid [selection clause](#selection-clauses), either simple or using [set operations](#set-operations).                                                                                                                            |
| `sort_clause`        | An optional `ORDER BY` clause. See <InternalLink path="order-by">Ordering Query Results</InternalLink> for details.                                                                                                                  |
| `limit_clause`       | An optional `LIMIT` clause. See <InternalLink path="limit-offset">Limit Query Results</InternalLink> for details.                                                                                                                    |
| `offset_clause`      | An optional `OFFSET` clause. See <InternalLink path="limit-offset">Limit Query Results</InternalLink> for details.                                                                                                                   |
| `for_locking_clause` | The `FOR UPDATE` locking clause is used to order transactions by controlling concurrent access to one or more rows of a table.  For more information, see <InternalLink path="select-for-update">`SELECT FOR UPDATE`</InternalLink>. |

The optional `LIMIT` and `OFFSET` clauses can appear in any order, but if also present, must appear **after** `ORDER BY`.

## Selection clauses

A *selection clause* is the main component of a selection query. A selection clause
defines tabular data. There are four specific syntax forms:

| Form                              | Usage                                                                                        |
| --------------------------------- | -------------------------------------------------------------------------------------------- |
| [`SELECT`](#select-clause)        | Load or compute tabular data from various sources. This is the most common selection clause. |
| [`VALUES`](#values-clause)        | List tabular data by the client.                                                             |
| [`TABLE`](#table-clause)          | Load tabular data from the database.                                                         |
| [Set operations](#set-operations) | Combine tabular data from two or more selection clauses.                                     |

### Synopsis

<img src="https://mintcdn.com/cockroachlabs/hRoSoqt0mqHbZVjm/images/sql-diagrams/v23.1/select_clause.svg?fit=max&auto=format&n=hRoSoqt0mqHbZVjm&q=85&s=99adc3c32a65fdadb74de4992c329997" alt="select_clause syntax diagram" style={{maxWidth: "100%", overflowX: "auto"}} width="385" height="345" data-path="images/sql-diagrams/v23.1/select_clause.svg" />

### `VALUES` clause

<img src="https://mintcdn.com/cockroachlabs/hRoSoqt0mqHbZVjm/images/sql-diagrams/v23.1/values_clause.svg?fit=max&auto=format&n=hRoSoqt0mqHbZVjm&q=85&s=e786efc20044af714d5650180a6dfa62" alt="values_clause syntax diagram" style={{maxWidth: "100%", overflowX: "auto"}} width="387" height="125" data-path="images/sql-diagrams/v23.1/values_clause.svg" />

#### Syntax

A `VALUES` clause defines tabular data defined by the expressions
listed within parentheses. Each parenthesis group defines a single row
in the resulting table.

The columns of the resulting table data have automatically generated names. When the `VALUES` clause is used as a <InternalLink path="subqueries">subquery</InternalLink>,
you can modify these names with <InternalLink path="table-expressions#aliased-table-expressions">`AS`</InternalLink>.

#### Example

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> VALUES (1, 2, 3), (4, 5, 6);
```

```
+---------+---------+---------+
| column1 | column2 | column3 |
+---------+---------+---------+
|       1 |       2 |       3 |
|       4 |       5 |       6 |
+---------+---------+---------+
```

### `TABLE` clause

<img src="https://mintcdn.com/cockroachlabs/hRoSoqt0mqHbZVjm/images/sql-diagrams/v23.1/table_clause.svg?fit=max&auto=format&n=hRoSoqt0mqHbZVjm&q=85&s=6aad4b872d4434cb2674e4b440542933" alt="table_clause syntax diagram" style={{maxWidth: "100%", overflowX: "auto"}} width="219" height="37" data-path="images/sql-diagrams/v23.1/table_clause.svg" />

#### Syntax

A `TABLE` clause reads tabular data from a specified table. The
columns of the resulting table data are named after the schema of the
table.

`TABLE x` is equivalent to `SELECT * FROM x`.

#### Example

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> CREATE TABLE employee_copy AS TABLE employee;
```

This statement copies the content from table `employee` into a new
table. However, the `TABLE` clause does not preserve the indexing,
foreign key, or constraint and default information from the schema of the
table it reads from, so in this example, the new table `employee_copy`
will likely have a simpler schema than `employee`.

Other examples:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> TABLE employee;
```

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> INSERT INTO employee_copy TABLE employee;
```

### `SELECT` clause

See <InternalLink path="select-clause">Simple `SELECT` Clause</InternalLink> for more
details.

## Set operations

Set operations combine data from two [selection
clauses](#selection-clauses). They are valid as operand to other
set operations or as main component in a selection query.

### Synopsis

<img src="https://mintcdn.com/cockroachlabs/hRoSoqt0mqHbZVjm/images/sql-diagrams/v23.1/set_operation.svg?fit=max&auto=format&n=hRoSoqt0mqHbZVjm&q=85&s=ac565bec9e34c4fa131a1cb54af08e05" alt="set_operation syntax diagram" style={{maxWidth: "100%", overflowX: "auto"}} width="593" height="125" data-path="images/sql-diagrams/v23.1/set_operation.svg" />

### Set operators

SQL lets you compare the results of multiple [selection clauses](#selection-clauses). You can think of each of the set operators as representing a Boolean operator:

* `UNION` = `OR`
* `INTERSECT` = `AND`
* `EXCEPT` = `NOT`

By default, each of these comparisons displays only one copy of each value (similar to `SELECT DISTINCT`). However, to display duplicate values, you can add an `ALL` to the clause.

### `UNION`: Combine two queries

`UNION` combines the results of two queries into one result.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT name
FROM accounts
WHERE state_opened IN ('AZ', 'NY')
UNION
SELECT name
FROM mortgages
WHERE state_opened IN ('AZ', 'NY');
```

```
+-----------------+
|      name       |
+-----------------+
| Naseem Joossens |
| Ricarda Caron   |
| Carola Dahl     |
| Aygün Sanna     |
+-----------------+
```

To show duplicate rows, you can use `ALL`.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT name
FROM accounts
WHERE state_opened IN ('AZ', 'NY')
UNION ALL
SELECT name
FROM mortgages
WHERE state_opened IN ('AZ', 'NY');
```

```
+-----------------+
|      name       |
+-----------------+
| Naseem Joossens |
| Ricarda Caron   |
| Carola Dahl     |
| Naseem Joossens |
| Aygün Sanna     |
| Carola Dahl     |
+-----------------+
```

### `INTERSECT`: Retrieve intersection of two queries

`INTERSECT` selects only values that are present in both query operands.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT name
FROM accounts
WHERE state_opened IN ('NJ', 'VA')
INTERSECT
SELECT name
FROM mortgages;
```

```
+-----------------+
|      name       |
+-----------------+
| Danijel Whinery |
| Agar Archer     |
+-----------------+
```

### `EXCEPT`: Exclude one query's results from another

`EXCEPT` selects values that are present in the first query operand but not the second.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT name
FROM mortgages
EXCEPT
SELECT name
FROM accounts;
```

```
+------------------+
|       name       |
+------------------+
| Günay García     |
| Karla Goddard    |
| Cybele Seaver    |
+------------------+
```

## Order results

The following sections provide examples. For more details, see <InternalLink path="order-by">`ORDER BY`</InternalLink>.

### Order retrieved rows by one column

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT *
FROM accounts
WHERE balance BETWEEN 350 AND 500
ORDER BY balance DESC;
```

```
+----+--------------------+---------+----------+--------------+
| id |        name        | balance |   type   | state_opened |
+----+--------------------+---------+----------+--------------+
| 12 | Raniya Žitnik      |     500 | savings  | CT           |
| 59 | Annibale Karga     |     500 | savings  | ND           |
| 27 | Adelbert Ventura   |     500 | checking | IA           |
| 86 | Theresa Slaski     |     500 | checking | WY           |
| 73 | Ruadh Draganov     |     500 | checking | TN           |
| 16 | Virginia Ruan      |     400 | checking | HI           |
| 43 | Tahirih Malinowski |     400 | checking | MS           |
| 50 | Dusan Mallory      |     350 | savings  | NV           |
+----+--------------------+---------+----------+--------------+
```

### Order retrieved rows by multiple columns

Columns are sorted in the order you list them in `sortby_list`. For example, `ORDER BY a, b` sorts the rows by column `a` and then sorts rows with the same `a` value by their column `b` values.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT *
FROM accounts
WHERE balance BETWEEN 350 AND 500
ORDER BY balance DESC, name ASC;
```

```
+----+--------------------+---------+----------+--------------+
| id |        name        | balance |   type   | state_opened |
+----+--------------------+---------+----------+--------------+
| 27 | Adelbert Ventura   |     500 | checking | IA           |
| 59 | Annibale Karga     |     500 | savings  | ND           |
| 12 | Raniya Žitnik      |     500 | savings  | CT           |
| 73 | Ruadh Draganov     |     500 | checking | TN           |
| 86 | Theresa Slaski     |     500 | checking | WY           |
| 43 | Tahirih Malinowski |     400 | checking | MS           |
| 16 | Virginia Ruan      |     400 | checking | HI           |
| 50 | Dusan Mallory      |     350 | savings  | NV           |
+----+--------------------+---------+----------+--------------+
```

## Limit row count

You can reduce the number of results with `LIMIT`.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT id, name
FROM accounts
LIMIT 5;
```

```
+----+------------------+
| id |       name       |
+----+------------------+
|  1 | Bjorn Fairclough |
|  2 | Bjorn Fairclough |
|  3 | Arturo Nevin     |
|  4 | Arturo Nevin     |
|  5 | Naseem Joossens  |
+----+------------------+
```

## Row-level locking for concurrency control with `SELECT FOR UPDATE`

The `SELECT FOR UPDATE` statement is used to order transactions by controlling concurrent access to one or more rows of a table.

It works by locking the rows returned by a [selection query][selection], such that other transactions trying to access those rows are forced to wait for the transaction that locked the rows to finish. These other transactions are effectively put into a queue based on when they tried to read the value of the locked rows.

Because this queueing happens during the read operation, the [thrashing](https://wikipedia.org/wiki/Thrashing_\(computer_science\)) that would otherwise occur if multiple concurrently executing transactions attempt to `SELECT` the same data and then `UPDATE` the results of that selection is prevented. By preventing thrashing, CockroachDB also prevents [transaction retries][retries] that would otherwise occur due to <InternalLink path="performance-best-practices-overview#transaction-contention">contention</InternalLink>.

As a result, using `SELECT FOR UPDATE` leads to increased throughput and decreased tail latency for contended operations.

Note that using `SELECT FOR UPDATE` does not completely eliminate the chance of <InternalLink path="transaction-retry-error-reference">serialization errors</InternalLink>, which use the `SQLSTATE` error code `40001`, and emit error messages with the string `restart transaction`. These errors can also arise due to <InternalLink path="architecture/transaction-layer#transaction-conflicts">time uncertainty</InternalLink>. To eliminate the need for application-level retry logic, in addition to `SELECT FOR UPDATE` your application also needs to use a <InternalLink path="transaction-retry-error-reference#client-side-retry-handling">driver that implements automatic retry handling</InternalLink>.

CockroachDB does not support the `FOR SHARE` or `FOR KEY SHARE` <InternalLink path="select-for-update#locking-strengths">locking strengths</InternalLink>.

<Note>
  By default, CockroachDB uses the `SELECT FOR UPDATE` locking mechanism during the initial row scan performed in <InternalLink path="update">`UPDATE`</InternalLink> and <InternalLink path="upsert">`UPSERT`</InternalLink> statement execution. To turn off implicit `SELECT FOR UPDATE` locking for `UPDATE` and `UPSERT` statements, set the `enable_implicit_select_for_update` <InternalLink path="set-vars">session variable</InternalLink> to `false`.
</Note>

[retries]: transactions.html#transaction-retries

[selection]: selection-queries.html

For an example showing how to use it, see  <InternalLink path="select-for-update">`SELECT FOR UPDATE`</InternalLink>.

## Composability

[Selection clauses](#selection-clauses) are defined in the context of selection queries. <InternalLink path="table-expressions">Table expressions</InternalLink> are defined in the context of the `FROM` sub-clause of <InternalLink path="select-clause">`SELECT`</InternalLink>. Nevertheless, you can integrate them with one another to form more complex queries or statements.

### Use a selection clause as a selection query

You can use a [selection clause](#selection-clauses) as a
selection query with no change.

For example, the construct <InternalLink path="select-clause">`SELECT * FROM accounts`</InternalLink> is a selection clause. It is also a valid selection query, and thus can be used as a stand-alone statement by appending a semicolon:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT * FROM accounts;
```

```
+----+-----------------------+---------+----------+--------------+
| id |         name          | balance |   type   | state_opened |
+----+-----------------------+---------+----------+--------------+
|  1 | Bjorn Fairclough      |    1200 | checking | AL           |
|  2 | Bjorn Fairclough      |    2500 | savings  | AL           |
|  3 | Arturo Nevin          |     250 | checking | AK           |
[ truncated ]
+----+-----------------------+---------+----------+--------------+
```

Likewise, the construct [`VALUES (1), (2), (3)`](#values-clause) is also a selection
clause and thus can also be used as a selection query on its own:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> VALUES (1), (2), (3);
```

```
+---------+
| column1 |
+---------+
|       1 |
|       2 |
|       3 |
+---------+
(3 rows)
```

### Use a table expression as selection clause

You can use a <InternalLink path="table-expressions">table expression</InternalLink> as a selection clause (and thus also a selection query) by prefixing it with `TABLE` or by using it as an operand to `SELECT * FROM`.

For example, the <InternalLink path="table-expressions#table-and-view-names">simple table name</InternalLink> `customers` is a table expression, which designates all rows in that table. The expressions <InternalLink path="selection-queries#table-clause">`TABLE accounts`</InternalLink> and <InternalLink path="select-clause">`SELECT * FROM accounts`</InternalLink> are valid selection clauses.

Likewise, the <InternalLink path="joins">SQL join expression</InternalLink> `customers c JOIN orders o ON c.id = o.customer_id` is a table expression. You can turn it into a valid selection clause, and thus a valid selection query as follows:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> TABLE (customers c JOIN orders o ON c.id = o.customer_id);
```

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT * FROM customers c JOIN orders o ON c.id = o.customer_id;
```

### Use a selection query as table expression

You can use a selection query (or [selection clause](#selection-clauses)) as a <InternalLink path="table-expressions">table
expression</InternalLink> by enclosing it between parentheses, which forms a
<InternalLink path="table-expressions#use-a-subquery">subquery</InternalLink>.

For example, the following construct is a selection query, but is not a valid table expression:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT * FROM customers ORDER BY name LIMIT 5
```

To make it valid as operand to `FROM` or another table expression, you can enclose it between parentheses as follows:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT id FROM (SELECT * FROM customers ORDER BY name LIMIT 5);
```

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT o.id
    FROM orders o
    JOIN (SELECT * FROM customers ORDER BY name LIMIT 5) AS c
	  ON o.customer_id = c.id;
```

### Use selection queries with other statements

Selection queries are also valid as operand in contexts that require tabular data.

For example:

| Statement                                                                              | Example using `SELECT`                                                                      | Example using `VALUES`                              | Example using `TABLE`                      |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------ |
| <InternalLink path="insert">`INSERT`</InternalLink>                                    | `INSERT INTO foo SELECT * FROM bar`                                                         | `INSERT INTO foo VALUES (1), (2), (3)`              | `INSERT INTO foo TABLE bar`                |
| <InternalLink path="upsert">`UPSERT`</InternalLink>                                    | `UPSERT INTO foo SELECT * FROM bar`                                                         | `UPSERT INTO foo VALUES (1), (2), (3)`              | `UPSERT INTO foo TABLE bar`                |
| <InternalLink path="create-table-as">`CREATE TABLE AS`</InternalLink>                  | `CREATE TABLE foo AS SELECT * FROM bar`  `CREATE TABLE foo AS VALUES (1),(2),(3)`           | `CREATE TABLE foo AS TABLE bar`                     |                                            |
| <InternalLink path="alter-table#split-at">`ALTER ... SPLIT AT`</InternalLink>          | `ALTER TABLE foo SPLIT AT SELECT * FROM bar`  `ALTER TABLE foo SPLIT AT VALUES (1),(2),(3)` | `ALTER TABLE foo SPLIT AT TABLE bar`                |                                            |
| Subquery in a <InternalLink path="table-expressions">table expression</InternalLink>   | `SELECT * FROM (SELECT * FROM bar)`                                                         | `SELECT * FROM (VALUES (1),(2),(3))`                | `SELECT * FROM (TABLE bar)`                |
| Subquery in a <InternalLink path="scalar-expressions">scalar expression</InternalLink> | `SELECT * FROM foo WHERE x IN (SELECT * FROM bar)`                                          | `SELECT * FROM foo WHERE x IN (VALUES (1),(2),(3))` | `SELECT * FROM foo WHERE x IN (TABLE bar)` |

## See also

* <InternalLink path="select-clause">Simple `SELECT` Clause</InternalLink>
* <InternalLink path="select-for-update">`SELECT FOR UPDATE`</InternalLink>
* <InternalLink path="table-expressions">Table Expressions</InternalLink>
* <InternalLink path="order-by">Ordering Query Results</InternalLink>
* <InternalLink path="limit-offset">Limit Query Results</InternalLink>
