---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.6
alternate:
  - https://ydb.tech/docs/en/yql/reference/syntax/select.md?version=main
  - https://ydb.tech/docs/ru/yql/reference/syntax/select.md?version=main
sourcePath: ru/core/yql/reference/syntax/select/index.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ydb.tech/docs/ru/llms.txt

## SELECT

Возвращает результат вычисления выражений, указанных после `SELECT`.

Может использоваться в сочетании с другими операциями для получения иного эффекта.

### Примеры

```yql
SELECT "Hello, world!";
```

```yql
SELECT 2 + 2;
```

## Процедура выполнения SELECT {#selectexec}

Результат запроса `SELECT` вычисляется следующим образом:

* определяется набор входных таблиц – вычисляются выражения после [FROM](https://ydb.tech/docs/ru/yql/reference/syntax/select/from.md?version=main);
* выполняется [FLATTEN COLUMNS](https://ydb.tech/docs/ru/yql/reference/syntax/select/flatten.md?version=main#flatten-columns) или [FLATTEN BY](https://ydb.tech/docs/ru/yql/reference/syntax/select/flatten.md?version=main); алиасы, заданные во `FLATTEN BY`, становятся видны после этой точки;
* выполняются все [JOIN](https://ydb.tech/docs/ru/yql/reference/syntax/select/join.md?version=main);
* к полученным данным добавляются (или заменяются) колонки, заданные в [GROUP BY ... AS ...](https://ydb.tech/docs/ru/yql/reference/syntax/select/group-by.md?version=main);
* выполняется [WHERE](https://ydb.tech/docs/ru/yql/reference/syntax/select/where.md?version=main): все данные, не удовлетворяющие предикату, отфильтровываются;
* выполняется [GROUP BY](https://ydb.tech/docs/ru/yql/reference/syntax/select/group-by.md?version=main), вычисляются значения агрегатных функций;
* выполняется фильтрация [HAVING](https://ydb.tech/docs/ru/yql/reference/syntax/select/group-by.md?version=main#having);
* вычисляются значения [оконных функций](https://ydb.tech/docs/ru/yql/reference/syntax/select/window.md?version=main);
* вычисляются выражения в `SELECT`;
* выражениям в `SELECT` назначаются имена заданные алиасами;
* к полученным таким образом колонкам применяется top-level [DISTINCT](https://ydb.tech/docs/ru/yql/reference/syntax/select/distinct.md?version=main);
* таким же образом вычисляются все подзапросы в [UNION ALL](https://ydb.tech/docs/ru/yql/reference/syntax/select/union.md?version=main#union-all), выполняется их объединение (см. [PRAGMA AnsiOrderByLimitInUnionAll](https://ydb.tech/docs/ru/yql/reference/syntax/pragma.md?version=main#pragmas));
* выполняется сортировка согласно [ORDER BY](https://ydb.tech/docs/ru/yql/reference/syntax/select/order_by.md?version=main);
* к полученному результату применяются [OFFSET и LIMIT](https://ydb.tech/docs/ru/yql/reference/syntax/select/limit_offset.md?version=main).

## Порядок колонок в YQL {#orderedcolumns}

В стандартном SQL порядок колонок указанных в проекции (в `SELECT`) имеет значение. Помимо того, что порядок колонок должен сохраняться при отображении результатов запроса или при записи в новую таблицу, некоторые конструкции SQL этот порядок используют.
Это относится в том числе к [UNION ALL](https://ydb.tech/docs/ru/yql/reference/syntax/select/union.md?version=main#union-all) и к позиционному [ORDER BY](https://ydb.tech/docs/ru/yql/reference/syntax/select/order_by.md?version=main) (ORDER BY ordinal).

По умолчанию в YQL порядок колонок игнорируется:

* порядок колонок в выходных таблицах и в результатах запроса не определен
* схема данных результата `UNION ALL` выводится по именам колонок, а не по позициям

При включении `PRAGMA OrderedColumns;` порядок колонок сохраняется в результатах запроса и выводится из порядка колонок во входных таблицах по следующим правилам:

* `SELECT` с явным перечислением колонок задает соответствующий порядок;
* `SELECT` со звездочкой (`SELECT * FROM ...`) наследует порядок из своего входа;

* порядок колонок после [JOIN](https://ydb.tech/docs/ru/yql/reference/syntax/select/join.md?version=main): сначала колонки левой стороны, потом правой. Если порядок какой-либо из сторон, присутствующей в выходе `JOIN`, не определен, порядок колонок результата также не определен;

* порядок `UNION ALL` зависит от режима выполнения [UNION ALL](https://ydb.tech/docs/ru/yql/reference/syntax/select/union.md?version=main#union-all);
* порядок колонок для [AS_TABLE](https://ydb.tech/docs/ru/yql/reference/syntax/select/from_as_table.md?version=main) не определен;


## Комбинация запросов {#combining-queries}

Результаты нескольких SELECT (или подзапросов) могут быть объединены с помощью ключевых слов `UNION` и `UNION ALL`.

```yql
query1 UNION [ALL] query2 (UNION [ALL] query3 ...)
```

Объединение более двух запросов интерпретируется как левоассоциативная операция, то есть

```yql
query1 UNION query2 UNION ALL query3
```

интерпретируется как

```yql
(query1 UNION query2) UNION ALL query3
```

При наличии `ORDER BY/LIMIT/DISCARD/INTO RESULT` в объединяемых подзапросах применяются следующие правила:

* `ORDER BY/LIMIT/INTO RESULT` допускается только после последнего подзапроса;
* `DISCARD` допускается только перед первым подзапросом;
* указанные операторы действуют на результат `UNION [ALL]`, а не на подзапрос;
* чтобы применить оператор к подзапросу, подзапрос необходимо взять в скобки.


## Обращение к нескольким таблицам в одном запросе

В стандартном SQL для выполнения запроса по нескольким таблицам используется [UNION ALL](https://ydb.tech/docs/ru/yql/reference/syntax/select/union.md?version=main#union-all), который объединяет результаты двух и более `SELECT`. Это не совсем удобно для сценария использования, в котором требуется выполнить один и тот же запрос по нескольким таблицам (например, содержащим данные на разные даты). В YQL, чтобы было удобнее, в `SELECT` после `FROM` можно указывать не только одну таблицу или подзапрос, но и вызывать встроенные функции, позволяющие объединять данные нескольких таблиц.

Для этих целей определены следующие функции:

```CONCAT(`table1`, `table2`, `table3` VIEW view_name, ...)``` — объединяет все перечисленные в аргументах таблицы.

`EACH($list_of_strings)` или `EACH($list_of_strings VIEW view_name)` — объединяет все таблицы, имена которых перечислены в списке строк. Опционально можно передать несколько списков в отдельных аргументах по аналогии с `CONCAT`.

```RANGE(`prefix`, `min`, `max`, `suffix`, `view`)``` — объединяет диапазон таблиц. Аргументы:

* prefix — каталог для поиска таблиц, указывается без завершающего слеша. Единственный обязательный аргумент, если указан только он, то используются все таблицы в данном каталоге.
* min, max — следующие два аргумента задают диапазон имен для включения таблиц. Диапазон инклюзивный с обоих концов. Если диапазон не указан, используются все таблицы в каталоге prefix. Имена таблиц или директорий, находящихся в указанной в prefix директории, сравниваются с диапазоном `[min, max]` лексикографически, а не конкатенируются, таким образом важно указывать диапазон без лидирующих слешей.
* suffix — имя таблицы. Ожидается без начального слеша. Если suffix не указан, то аргументы `[min, max]` задают диапазон имен таблиц. Если suffix указан, то аргументы `[min, max]` задают диапазон папок, в которых существует таблица с именем, указанным в аргументе suffix.

```LIKE(`prefix`, `pattern`, `suffix`, `view`)` и `REGEXP(`prefix`, `pattern`, `suffix`, `view`)``` — аргумент pattern задается в формате, аналогичном одноименным бинарным операторам: [LIKE](https://ydb.tech/docs/ru/yql/reference/syntax/expressions.md?version=main#like) и [REGEXP](https://ydb.tech/docs/ru/yql/reference/syntax/expressions.md?version=main#regexp).

```FILTER(`prefix`, `callable`, `suffix`, `view`)``` — аргумент callable должен являться вызываемым выражением с сигнатурой `(String)->Bool`, который будет вызван для каждой таблицы/подкаталога в каталоге prefix. В запросе будут участвовать только те таблицы, для которых вызываемое значение вернуло `true`. В качестве вызываемого значения удобнее всего использовать [лямбда функции](https://ydb.tech/docs/ru/yql/reference/syntax/expressions.md?version=main#lambda).

{% note warning %}

Порядок, в котором будут объединены таблицы, всеми вышеперечисленными функциями не гарантируется.

Список таблиц вычисляется **до** запуска самого запроса. Поэтому созданные в процессе запроса таблицы не попадут в результаты функции.

{% endnote %}

По умолчанию схемы всех участвующих таблиц объединяются по правилам [UNION ALL](https://ydb.tech/docs/ru/yql/reference/syntax/select/union.md?version=main#union-all). Если объединение схем не желательно, то можно использовать функции с суффиксом `_STRICT`, например `CONCAT_STRICT` или `RANGE_STRICT`, которые работают полностью аналогично оригинальным, но считают любое расхождение в схемах таблиц ошибкой.

Для указания кластера объединяемых таблиц нужно указать его перед названием функции.

Все аргументы описанных выше функций могут быть объявлены отдельно через [именованные выражения](https://ydb.tech/docs/ru/yql/reference/syntax/expressions.md?version=main#named-nodes). В этом случае в них также допустимы и простые выражения посредством неявного вызова [EvaluateExpr](https://ydb.tech/docs/ru/yql/reference/builtins/basic.md?version=main#evaluate_expr_atom).

Имя исходной таблицы, из которой изначально была получена каждая строка, можно получить при помощи функции [TablePath()](https://ydb.tech/docs/ru/yql/reference/builtins/basic.md?version=main#tablepath).

### Примеры

```yql
SELECT * FROM CONCAT(
  `table1`,
  `table2`,
  `table3`);
```

```yql
$indices = ListFromRange(1, 4);
$tables = ListMap($indices, ($index) -> {
    RETURN "table" || CAST($index AS String);
});
SELECT * FROM EACH($tables); -- идентично предыдущему примеру
```

```yql
SELECT * FROM RANGE(`my_folder`);
```

```yql
SELECT * FROM some_cluster.RANGE( -- Кластер можно указать перед названием функции
  `my_folder`,
  `from_table`,
  `to_table`);
```

```yql
SELECT * FROM RANGE(
  `my_folder`,
  `from_folder`,
  `to_folder`,
  `my_table`);
```

```yql
SELECT * FROM RANGE(
  `my_folder`,
  `from_table`,
  `to_table`,
  ``,
  `my_view`);
```

```yql
SELECT * FROM LIKE(
  `my_folder`,
  "2017-03-%"
);
```

```yql
SELECT * FROM REGEXP(
  `my_folder`,
  "2017-03-1[2-4]?"
);
```

```yql
$callable = ($table_name) -> {
    return $table_name > "2017-03-13";
};

SELECT * FROM FILTER(
  `my_folder`,
  $callable
);
```

## Поддерживаемые конструкции в SELECT

* [FROM](https://ydb.tech/docs/ru/yql/reference/syntax/select/from.md?version=main)
* [FROM AS_TABLE](https://ydb.tech/docs/ru/yql/reference/syntax/select/from_as_table.md?version=main)
* [FROM SELECT](https://ydb.tech/docs/ru/yql/reference/syntax/select/from_select.md?version=main)
* [DISTINCT](https://ydb.tech/docs/ru/yql/reference/syntax/select/distinct.md?version=main)
* [UNIQUE DISTINCT](https://ydb.tech/docs/ru/yql/reference/syntax/select/unique_distinct_hints.md?version=main)
* [UNION](https://ydb.tech/docs/ru/yql/reference/syntax/select/union.md?version=main)
* [WITH](https://ydb.tech/docs/ru/yql/reference/syntax/select/with.md?version=main)
* [WITHOUT](https://ydb.tech/docs/ru/yql/reference/syntax/select/without.md?version=main)
* [WHERE](https://ydb.tech/docs/ru/yql/reference/syntax/select/where.md?version=main)
* [ORDER BY](https://ydb.tech/docs/ru/yql/reference/syntax/select/order_by.md?version=main)
* [ASSUME ORDER BY](https://ydb.tech/docs/ru/yql/reference/syntax/select/assume_order_by.md?version=main)
* [LIMIT OFFSET](https://ydb.tech/docs/ru/yql/reference/syntax/select/limit_offset.md?version=main)
* [JOIN](https://ydb.tech/docs/ru/yql/reference/syntax/select/join.md?version=main)
* [GROUP BY](https://ydb.tech/docs/ru/yql/reference/syntax/select/group-by.md?version=main)
* [FLATTEN](https://ydb.tech/docs/ru/yql/reference/syntax/select/flatten.md?version=main)
* [WINDOW](https://ydb.tech/docs/ru/yql/reference/syntax/select/window.md?version=main)






* [VIEW secondary_index](https://ydb.tech/docs/ru/yql/reference/syntax/select/secondary_index.md?version=main)

* [VIEW vector_index](https://ydb.tech/docs/ru/yql/reference/syntax/select/vector_index.md?version=main)
* [VIEW fulltext_index](https://ydb.tech/docs/ru/yql/reference/syntax/select/fulltext_index.md?version=main)
* [VIEW json_index](https://ydb.tech/docs/ru/yql/reference/syntax/select/json_index.md?version=main)

