Я бы полагался на функции массива, чтобы сделать поведение предсказуемым.
Примечания:
не должно быть никаких внешних вставок в таблицы назначения и исходные таблицы
должен запускаться только один скрипт за раз (поэтому не применяйте его к распределенной таблице, а последовательно выполняйте на каждом сегменте)
для огромная таблица, вложенный запрос может завершиться неудачно, поэтому имеет смысл добавить предложение WHERE, чтобы ограничить количество обрабатываемых данных
INSERT INTO target
SELECT result.1 AS id, result.2 AS name
FROM (
WITH (SELECT max(id) FROM target) AS target_table_max_id
SELECT
groupArray((id, name)) origin_data,
arrayMap((origin_row, row_index) -> (target_table_max_id + row_index, origin_row.2),
origin_data,
arrayEnumerate(origin_data)) origin_data_updated,
arrayJoin(origin_data_updated) result
FROM origin);
Скрипты для подготовки тестовой среды:
# prepare test tables
CREATE TABLE target (`id` Int32, `name` String) ENGINE = Memory;
CREATE TABLE origin (`id` Int32, `name` String) ENGINE = Memory;
# fill test tables
INSERT INTO target
SELECT number AS id, toString(id) AS name
FROM numbers(8);
INSERT INTO origin
SELECT number + 2048 AS id, toString(id) AS name
FROM numbers(4);