> ## 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/kYb5CU8_1XGPxWhU/images/sql-diagrams/v24.1/select.svg?fit=max&auto=format&n=kYb5CU8_1XGPxWhU&q=85&s=652365c99476d7d4f74c978990a35d1f" alt="select syntax diagram" style={{maxWidth: "100%", overflowX: "auto"}} width="1349" height="505" data-path="images/sql-diagrams/v24.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` and `FOR SHARE` clauses are used to lock `SELECT` statements. For more information, see <InternalLink path="select-for-update">`FOR UPDATE` and `FOR SHARE`</InternalLink>. |

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

<Note>
  Because the `WITH`, `ORDER BY`, `LIMIT`, and `OFFSET` sub-clauses are all optional, any simple [selection clause](#selection-clauses) is also a valid selection query.
</Note>

## 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.                                     |

<Note>
  To perform joins or other relational operations over selection clauses, use a <InternalLink path="table-expressions">table expression</InternalLink> and [convert it back](#composability) into a selection clause with [`TABLE`](#table-clause) or [`SELECT`](#select-clause).
</Note>

### Synopsis

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

### `VALUES` clause

<img src="https://mintcdn.com/cockroachlabs/kYb5CU8_1XGPxWhU/images/sql-diagrams/v24.1/values_clause.svg?fit=max&auto=format&n=kYb5CU8_1XGPxWhU&q=85&s=edd8e134b61b1aaf1786fbd74d6f67dc" alt="values_clause syntax diagram" style={{maxWidth: "100%", overflowX: "auto"}} width="387" height="125" data-path="images/sql-diagrams/v24.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);
```

```text theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
+---------+---------+---------+
| column1 | column2 | column3 |
+---------+---------+---------+
|       1 |       2 |       3 |
|       4 |       5 |       6 |
+---------+---------+---------+
```

### `TABLE` clause

<img src="https://mintcdn.com/cockroachlabs/kYb5CU8_1XGPxWhU/images/sql-diagrams/v24.1/table_clause.svg?fit=max&auto=format&n=kYb5CU8_1XGPxWhU&q=85&s=0a08d61a4c837afdbfbca70fbdea6970" alt="table_clause syntax diagram" style={{maxWidth: "100%", overflowX: "auto"}} width="219" height="37" data-path="images/sql-diagrams/v24.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`.

<Note>
  Any <InternalLink path="table-expressions">table expression</InternalLink> between parentheses is a valid operand for `TABLE`, not just <InternalLink path="table-expressions#table-and-view-names">simple table or view names</InternalLink>.
</Note>

#### 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/kYb5CU8_1XGPxWhU/images/sql-diagrams/v24.1/set_operation.svg?fit=max&auto=format&n=kYb5CU8_1XGPxWhU&q=85&s=ff008b22ad704054332c59f8487f4d7c" alt="set_operation syntax diagram" style={{maxWidth: "100%", overflowX: "auto"}} width="593" height="125" data-path="images/sql-diagrams/v24.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');
```

```text theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
+-----------------+
|      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');
```

```text theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
+-----------------+
|      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;
```

```text theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
+-----------------+
|      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;
```

```text theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
+------------------+
|       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;
```

```text theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
+----+--------------------+---------+----------+--------------+
| 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;
```

```text theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
+----+--------------------+---------+----------+--------------+
| 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;
```

```text theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
+----+------------------+
| 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`

`SELECT... FOR UPDATE` exclusively locks the rows returned by a <InternalLink path="selection-queries">selection query</InternalLink>, such that other transactions trying to access those rows must wait for the transaction that locked the rows to commit or rollback.

`SELECT... FOR UPDATE` can be used to:

* Strengthen the isolation of a <InternalLink path="read-committed">`READ COMMITTED`</InternalLink> transaction. If you need to read and later update a row within a transaction, use `SELECT... FOR UPDATE` to acquire an exclusive lock on the row. This guarantees data integrity between the transaction's read and write operations. For details, see <InternalLink path="read-committed#locking-reads">Locking reads</InternalLink>.
* Order <InternalLink path="demo-serializable">`SERIALIZABLE`</InternalLink> transactions by controlling concurrent access to one or more rows of a table. These other transactions are placed into a queue based on when they tried to read the values 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, `SELECT... FOR UPDATE` also prevents <InternalLink path="transactions#transaction-retries">transaction retries</InternalLink> 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>. 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>.

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`.

For an example, see <InternalLink path="select-for-update">`FOR UPDATE` and `FOR SHARE`</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;
```

```text theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
+----+-----------------------+---------+----------+--------------+
| 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);
```

```text theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
+---------+
| 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>
