INSERT SELECT

Содержание раздела
  1. Синтаксис
    1. Ключевое слово SELECT
    2. Ключевое слово RETRY
  2. Ограничения
    1. Ограничения выполнения
    2. Ограничения сущностей
    3. Ограничения партиционирования
    4. Другие ограничения
  3. Примеры
    1. Вставка данных во все столбцы логической таблицы
    2. Вставка данных в некоторые столбцы логической таблицы
    3. Вставка данных в логическую таблицу вне дельты
    4. Вставка данных в логическую таблицу из другой логической БД
    5. Вставка данных из одного датасорса типа ADP в другой датасорс типа ADP
    6. Вставка данных в логическую таблицу из логического представления
    7. Заполнение столбца логической таблицы данными другой таблицы
    8. Вставка данных в логическую таблицу из standalone-таблицы
    9. Вставка данных в standalone-таблицу из логической таблицы
    10. Вставка данных в партиционированную таблицу из непартиционированной логической таблицы
    11. Вставка данных в партицию из непартиционированной логической таблицы
    12. Перезапуск операции по вставке записей

Поддерживается в версиях:  6.4 / 6.3 / 6.2 / 6.1 / 6.0 / 5.8 / 5.7 / 5.6 / 5.5 / 5.4 / 5.3 / 5.2.

Запрос вставляет записи в логическую таблицу или standalone-таблицу из другой логической сущности.

Синтаксис вставки в standalone-таблицу подразумевает использование внешней writable-таблицы, которая указывает на standalone-таблицу. При вставке данных в standalone-таблицу учитывайте ограничения таблиц в конкретной СУБД.

Вставка записей в логические и материализованные представления недоступна.

При вставке данных из standalone-таблицы в логическую таблицу обеспечьте неизменность данных в standalone-таблице на время работы запроса. Иначе вставка может привести к расхождениям данных между датасорсами.

Чтобы вставить большой объем данных, используйте загрузку данных или сочетание выгрузки и загрузки данных.

Источниками данных могут быть следующие сущности и их соединения:

Возможны следующие варианты вставки данных:

  • источник данных в датасорсе любого типа -> таблица-приемник, размещенная там же;
  • источник в датасорсе типа ADB -> таблица-приемник, размещенная в датасорсах следующих типов: ADP, ADG и (или) ADQM;
  • источник в датасорсе типа ADP -> таблица-приемник, размещенная в любых датасорсах типа ADP.

Расположением данных логической таблицы можно управлять с помощью запросов CREATE TABLE и DROP TABLE с ключевым словом DATASOURCE_TYPE. Первый запрос позволяет выбрать датасорсы для размещения данных таблицы, второй — удалить данные таблицы из выбранного датасорса.

Запрос обрабатывается в порядке, описанном в разделе Порядок обработки запросов на обновление данных.

В ответе возвращается:

  • объект ResultSet c одной записью, содержащей один столбец sysCn, при успешном выполнении запроса;
  • исключение при неуспешном выполнении запроса.

При вставке данных в логическую таблицу в столбце sysCn возвращается номер выполненной операции записи, при вставке во внешнюю writable-таблицу возвращается пустой столбец sysCn.

Записи выбираются из одного датасорса:

  • указанного в запросе или наиболее оптимального — если данные выбираются из логических таблиц, логических и материализованных представлений;
  • содержащего standalone-таблицу — если данные выбираются из standalone-таблицы или ее соединений с другими сущностями.

Записи вставляются в логическую таблицу следующим образом: если в текущей версии данных таблицы есть запись со значением первичного ключа, выбранным SELECT-запросом, запись обновляется; иначе добавляется новая запись. Все поля, указанные в запросе, заполняются значениями из запроса, а пропущенные поля — значениями по умолчанию.

При вставке данных в партиционированную таблицу система распределяет записи по соответствующим партициям. Если для записи не нашлось партиции с подходящим диапазоном партиционирования, эта запись игнорируется. При вставке данных напрямую в партицию вставляются только те записи, в которых значение ключа партиционирования соответствует одному из диапазонов партиционирования этой партиции.

Подробнее о партиционировании см. в разделе Партиционирование данных.

Незавершенную операцию по вставке данных можно перезапустить, повторив исходный запрос с ключевым словом RETRY. Подробнее о способах обработки незавершенных операций см. в разделе Управление операциями записи.

По умолчанию система ведет статистику обработки запросов к данным. Запросы INSERT SELECT учитываются в категории WRITE. Чтобы получить статистику, выполните GET_ENTITY_STATISTICS.

Синтаксис

Вставка данных во все столбцы таблицы:

INSERT INTO [db_name.]table_name SELECT query

Вставка данных в некоторые столбцы таблицы (с заполнением остальных столбцов значениями по умолчанию):

INSERT INTO [db_name.]table_name (column_list) SELECT query

Перезапуск операции по вставке данных:

RETRY INSERT INTO [db_name.]table_name [(column_list)] SELECT query

Параметры:

db_name

Имя логической базы данных. Опционально, если выбрана логическая БД, используемая по умолчанию.

table_name

Имя таблицы, в которую вставляются данные. Возможные значения:

column_list

Список имен столбцов указанной таблицы. Имена перечисляются в круглых скобках через запятую. Список опционален, если количество и порядок столбцов в SELECT-подзапросе соответствуют количеству и порядку столбцов в таблице.

query

SELECT-подзапрос для выбора данных.

Ключевое слово SELECT

Ключевое слово SELECT задает SELECT-подзапрос для выбора данных из источника.

Ключевое слово RETRY

Ключевое слово перезапускает обработку незавершенной операции записи, созданной запросом INSERT SELECT. Если ключевое слово не указано, система создает новую операцию и обрабатывает ее.

Пример запроса с ключевым словом RETRY см. ниже. Список незавершенных операций можно получить с помощью запроса GET_WRITE_OPERATIONS.

Перезапуск с ключевым словом RETRY доступен только для операций со статусом «Выполняется». Чтобы перезапустить операцию со статусом «Отменяется», выполните RESUME_WRITE_OPERATION. Подробнее о способах перезапуска и отмены операций см. в разделе Управление операциями записи.

Ключевое слово RETRY недоступно в запросах к standalone-таблицам.

Ограничения

Ограничения выполнения

  • Выполнение запроса недоступно, если есть незавершенная операция по изменению схемы.
  • Не допускается параллельное выполнение идентичных запросов.

Ограничения сущностей

  • Вставка данных в логические и материализованные представления недоступна.
  • Если данные вставляются из standalone-таблицы в логическую таблицу, данные standalone-таблицы должны оставаться неизменными во время работы запроса.

Ограничения партиционирования

  • При вставке данных в партиционированную таблицу все записи, для которых нет подходящей партиции, игнорируются.

Другие ограничения

  • Типы вставляемых значений должны соответствовать типам данных столбцов в таблице-приемнике.
  • Ключевое слово RETRY недоступно в запросах к standalone-таблицам.

Примеры

Вставка данных во все столбцы логической таблицы

-- выбор логической базы данных marketing в качестве базы данных по умолчанию
USE marketing;

-- создание логической таблицы sales_july_2021 с данными о продажах за июль 2021 (с размещением данных в датасорсе adb)
CREATE TABLE sales_july_2021 (
id BIGINT NOT NULL,
transaction_date TIMESTAMP NOT NULL,
product_code VARCHAR(256) NOT NULL,
product_units BIGINT NOT NULL,
store_id BIGINT NOT NULL,
description VARCHAR(256),
PRIMARY KEY (id)
) DISTRIBUTED BY (id)
DATASOURCE_TYPE ('adb');

-- открытие новой (горячей) дельты
BEGIN DELTA;

-- вставка данных из таблицы sales в таблицу sales_july_2021 
INSERT INTO sales_july_2021 
SELECT * FROM sales WHERE CAST(EXTRACT(MONTH FROM transaction_date) AS INT) = 7 AND 
  CAST(EXTRACT(YEAR FROM transaction_date) AS INT) = 2021 DATASOURCE_TYPE = 'adb';

-- закрытие дельты
COMMIT DELTA;

Вставка данных в некоторые столбцы логической таблицы

-- выбор логической базы данных marketing в качестве базы данных по умолчанию
USE marketing;

-- создание логической таблицы current_stores с размещением данных в датасорсе adqm
CREATE TABLE current_stores (
  id BIGINT NOT NULL,
  category VARCHAR(256),
  region VARCHAR(256),
  address VARCHAR(256),
  description VARCHAR(256),
  PRIMARY KEY (id)
)
DISTRIBUTED BY (id)
DATASOURCE_TYPE ('adqm');

-- открытие новой (горячей) дельты
BEGIN DELTA;

-- вставка данных в таблицу current_stores (столбец description пропущен)
INSERT INTO current_stores (id, category, region, address)
SELECT id, category, region, address FROM stores FOR SYSTEM_TIME AS OF DELTA_NUM 10 DATASOURCE_TYPE = 'adqm';

-- закрытие дельты
COMMIT DELTA;

Вставка данных в логическую таблицу вне дельты

-- вставка данных в таблицу current_stores вне дельты (столбец description пропущен)
INSERT INTO marketing.current_stores (id, category, region, address)
SELECT id, category, region, address FROM marketing.stores FOR SYSTEM_TIME AS OF DELTA_NUM 11 DATASOURCE_TYPE = 'adqm';

Вставка данных в логическую таблицу из другой логической БД

-- создание новой логической БД marketing_new
CREATE DATABASE marketing_new;

-- выбор логической базы данных marketing_new в качестве базы данных по умолчанию
USE marketing_new;

-- создание логической таблицы sales в логической БД marketing_new с размещением данных в датасорсе adp
CREATE TABLE sales (
id BIGINT NOT NULL,
transaction_date TIMESTAMP NOT NULL,
product_code VARCHAR(256) NOT NULL,
product_units BIGINT NOT NULL,
store_id BIGINT NOT NULL,
description VARCHAR(256),
PRIMARY KEY (id)
) DISTRIBUTED BY (id)
DATASOURCE_TYPE ('adp');

-- открытие новой (горячей) дельты
BEGIN DELTA;

-- вставка данных в таблицу sales из аналогичной таблицы логической БД marketing
INSERT INTO sales SELECT * FROM marketing.sales WHERE store_id BETWEEN 100 AND 200 DATASOURCE_TYPE = 'adp';

-- закрытие дельты
COMMIT DELTA;

Вставка данных из одного датасорса типа ADP в другой датасорс типа ADP

-- выбор логической базы данных marketing в качестве базы данных по умолчанию
USE marketing;

-- открытие новой (горячей) дельты
BEGIN DELTA;

-- вставка данных в таблицу clients_adp2 из таблицы clients_adp1
INSERT INTO marketing.clients_adp2 SELECT * FROM marketing.marketing.clients_adp1;

-- закрытие дельты
COMMIT DELTA;

Вставка данных в логическую таблицу из логического представления

-- выбор логической базы данных marketing в качестве базы данных по умолчанию
USE marketing;

-- создание логического представления basic_stores с данными о магазинах категории basic
CREATE VIEW basic_stores AS SELECT * FROM stores WHERE category = 'basic';

-- создание таблицы basic_stores_table с данными о магазинах категории basic (с размещением данных в датасорсах adb и adqm)
CREATE TABLE basic_stores_table (
id BIGINT NOT NULL,
category VARCHAR(256),
region VARCHAR(256),
address VARCHAR(256),
description VARCHAR(256),
PRIMARY KEY (id)
) DISTRIBUTED BY (id)
DATASOURCE_TYPE ('adb', 'adqm');

-- открытие новой (горячей) дельты
BEGIN DELTA;

-- вставка данных в таблицу basic_stores_table
INSERT INTO basic_stores_table SELECT * FROM basic_stores DATASOURCE_TYPE = 'adb';

-- закрытие дельты
COMMIT DELTA;

Заполнение столбца логической таблицы данными другой таблицы

-- выбор логической базы данных marketing в качестве базы данных по умолчанию
USE marketing;

-- создание логической таблицы с данными покупок и адресов магазинов, где были совершены покупки 
CREATE TABLE sales_with_address (
id BIGINT NOT NULL,
transaction_date TIMESTAMP NOT NULL,
product_code VARCHAR(256),
product_units BIGINT,
store_id BIGINT,
description VARCHAR(256),
store_address VARCHAR(256),
PRIMARY KEY (id)
) DISTRIBUTED BY (id)
DATASOURCE_TYPE ('adb', 'adg', 'adqm', 'adp');

-- открытие новой (горячей) дельты
BEGIN DELTA;

-- вставка данных из таблицы sales (заполнение всех столбцов, кроме store_address)
INSERT INTO sales_with_address (id, transaction_date, product_code, product_units, store_id, description)
SELECT * FROM sales DATASOURCE_TYPE = 'adb';

-- закрытие дельты
COMMIT DELTA;

-- открытие новой (горячей) дельты
BEGIN DELTA;

--- вставка данных адресов из таблицы stores в те строки, где адрес не заполнен
INSERT INTO sales_with_address
SELECT s.id, s.transaction_date, s.product_code, s.product_units, s.store_id, s.description, 
st.region || ', ' || st.address as store_address
FROM stores AS st 
JOIN sales_with_address AS s ON s.store_id = st.id 
WHERE s.store_address IS NULL OR s.store_address = ''
DATASOURCE_TYPE = 'adb';

-- закрытие дельты
COMMIT DELTA;

Вставка данных в логическую таблицу из standalone-таблицы

-- выбор логической базы данных marketing в качестве базы данных по умолчанию
USE marketing;

-- создание логической таблицы agreements_adp с размещением данных в датасорсе adp
CREATE TABLE agreements_adp (
  id BIGINT NOT NULL,
  client_id BIGINT NOT NULL,
  number VARCHAR NOT NULL,
  signature_date DATE,
  effective_date DATE,
  closing_date DATE,
  description VARCHAR,
  PRIMARY KEY(id)
)
DISTRIBUTED BY (id)
DATASOURCE_TYPE ('adp');

-- открытие новой (горячей) дельты
BEGIN DELTA;

-- вставка данных в логическую таблицу agreements_adp из standalone-таблицы, 
--   на которую указывает внешняя readable-таблица agreements_ext_read_adp
INSERT INTO agreements_adp SELECT * FROM agreements_ext_read_adp;

-- закрытие дельты
COMMIT DELTA;

Вставка данных в standalone-таблицу из логической таблицы

-- создание внешней writable-таблицы, связанной со standalone-таблицей датасорса adg
CREATE WRITABLE EXTERNAL TABLE marketing.sales_ext_write_adg (
  id BIGINT NOT NULL,
  transaction_date TIMESTAMP NOT NULL,
  product_code VARCHAR(256) NOT NULL,
  product_units BIGINT NOT NULL,
  store_id BIGINT NOT NULL,
  description VARCHAR(256),
  PRIMARY KEY (id)
)
DISTRIBUTED BY (id)
LOCATION 'core:adg://dtm__marketing__sales'
OPTIONS ('auto.create.table.enable=true');

-- вставка данных в standalone-таблицу, на которую указывает внешняя writable-таблица sales_ext_write_adg,
--   из логической таблицы sales
INSERT INTO marketing.sales_ext_write_adg SELECT * FROM marketing.sales DATASOURCE_TYPE = 'adg';

Вставка данных в партиционированную таблицу из непартиционированной логической таблицы

-- выбор логической базы данных marketing в качестве базы данных по умолчанию
USE marketing;

-- открытие новой (горячей) дельты
BEGIN DELTA;

-- вставка данных в партиционированную таблицу sales_partitioned
INSERT INTO sales_partitioned SELECT * FROM sales 
WHERE store_id <> 123
DATASOURCE_TYPE = 'adp';

-- закрытие дельты
COMMIT DELTA;

Вставка данных в партицию из непартиционированной логической таблицы

-- выбор логической базы данных marketing в качестве базы данных по умолчанию
USE marketing;

-- открытие новой (горячей) дельты
BEGIN DELTA;

-- вставка данных в партицию sales_feb_2023
INSERT INTO sales_feb_2023 SELECT * FROM sales 
WHERE store_id >= 123 AND product_code IN ('ABC0001', 'ABC0003', 'ABC0002')
DATASOURCE_TYPE = 'adp2';

-- закрытие дельты
COMMIT DELTA;

Перезапуск операции по вставке записей

-- выбор логической базы данных marketing в качестве базы данных по умолчанию
USE marketing;

-- открытие новой (горячей) дельты
BEGIN DELTA;
   
-- вставка записей в таблицу current_stores без указания значения столбца description
INSERT INTO current_stores 
       (id, category, region, address)
SELECT id, category, region, address 
FROM stores FOR SYSTEM_TIME AS OF DELTA_NUM 12 DATASOURCE_TYPE = 'adqm';

-- перезапуск обработки операции по вставке записи
RETRY INSERT INTO current_stores 
       (id, category, region, address)
SELECT id, category, region, address 
FROM stores FOR SYSTEM_TIME AS OF DELTA_NUM 12 DATASOURCE_TYPE = 'adqm';

-- закрытие дельты
COMMIT DELTA;