---
metadata:
  - name: generator
    content: Diplodoc Platform v5.52.0
alternate:
  - https://ydb.tech/docs/en/dev/streaming-query/table-writing.md?version=v25.4
  - https://ydb.tech/docs/ru/dev/streaming-query/table-writing.md?version=v25.4
  - href: ru/dev/streaming-query/table-writing.md
    type: text/markdown
    title: Markdown version
  - href: ../../llms.txt
    type: text/markdown
    title: llms.txt
sourcePath: ru/core/dev/streaming-query/table-writing.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ydb.tech/docs/ru/llms.txt

# Запись в таблицы

Запись в таблицы позволяет сохранять результаты потокового запроса для последующего анализа обычными SQL-запросами. Например, можно агрегировать события из потока и сохранять итоги в таблицу.

Для записи используется [UPSERT INTO](https://ydb.tech/docs/ru/yql/reference/syntax/upsert_into.md?version=v25.4) — вставка новой строки или обновление существующей по первичному ключу. Операция UPSERT идемпотентна по первичному ключу: повторная запись той же строки приводит к обновлению, а не к дублированию. Это важно, потому что потоковые запросы обеспечивают гарантию [at-least-once](https://ydb.tech/docs/ru/concepts/streaming-query.md?version=v25.4#guarantees) — при восстановлении из [чекпоинта](https://ydb.tech/docs/ru/dev/streaming-query/checkpoints.md?version=v25.4) часть событий может быть обработана повторно.

{% note alert %}

Не поддерживаются:

- команда [INSERT INTO](https://ydb.tech/docs/ru/yql/reference/syntax/insert_into.md?version=v25.4) — используйте UPSERT INTO. INSERT INTO не применяется, потому что при повторной обработке событий (гарантия at-least-once) она привела бы к дублированию строк;
- запись в таблицы YDB, находящиеся во внешних БД. В текущей версии запись возможна только в локальные таблицы.

{% endnote %}

## Пример

Запрос читает события из топика и записывает их в таблицу `output_table`. Поле `Ts` преобразуется из строки в тип `Timestamp` с помощью `CAST`, а [Unwrap](https://ydb.tech/docs/ru/yql/reference/builtins/basic.md?version=v25.4#unwrap) снимает опциональность результата.

```sql
CREATE STREAMING QUERY query_with_table_write AS
DO BEGIN

-- Чтение из топика и запись в таблицу
UPSERT INTO
    output_table
SELECT
    -- Преобразование строки в Timestamp
    Unwrap(CAST(Ts AS Timestamp)) AS Ts,
    Country,
    Count
FROM
    -- Чтение событий из топика
    ydb_source.input_topic
WITH (
    -- Формат данных в топике
    FORMAT = json_each_row,
    -- Схема данных
    SCHEMA = (
        Ts String NOT NULL,
        Count Uint64 NOT NULL,
        Country Utf8 NOT NULL
    )
);

END DO
```
