Это то, что сработало для меня:
merge into table_u a
using (select rd, i.id
from (select u.rowid rd, cnt - mod(rownum-1, cnt) rn
from table_u u, (select count(1) cnt from table_i) ) u
join (select row_number() over( order by id) rn, id from table_i) i using (rn)) b
on (a.rowid = b.rd)
when matched then update set a.user_id = b.id
Мои тестовые таблицы:
create table table_i as (
select level*10 id from dual connect by level <= 4);
create table table_u as (
select cast(null as number(3)) user_id, level id from dual connect by level <= 109);
Наибольшее значение из второй таблицы было присвоено 28 раз, остальные 27 раз. Это потому что я использовал
cnt - mod(rownum-1, cnt) rn
для подсчета присоединяющегося столбца. Хотя я не знаю, важно ли это для тебя. :) Основой этого решения является mod()
, что позволяет нам переключаться между 1
и cnt
(в данном случае 4).
Вы можете сделать это в PLSQL, как вы показали, но решения SQL, как правило, быстрее и предпочтительнее, когда это возможно.